/*Imageformat-dependentoperations.*/
typedefstruct{
jas_image_t*(*decode)(jas_stream_t*in,char*opts);
/*Decodeimagedatafromastream.*/
int(*encode)(jas_image_t*image,jas_stream_t*out,char*opts);
/*Encodeimagedatatoastream.*/
int(*validate)(jas_stream_t*in);
/*Determineifstreamdataisinaparticularformat.*/
}jas_image_fmtops_t;
/*Imageformatinformation.*/
typedefstruct{
intid;
/*TheIDforthisformat.*/
char*name;
/*Thenamebywhichthisformatisidentified.*/
char*ext;
/*Thefilenameextensionassociatedwiththisformat.*/
char*desc;
/*Abriefdescriptionoftheformat.*/
jas_image_fmtops_tops;
/*Theoperationsforthisformat.*/
}jas_image_fmtinfo_t;
这段代码是从jasper的源代码中摘抄出来的,jas_image_fmtops_t这个结构体定义了三个函数指针,是对图像的基本操作。s_image_fmtinfo_t描述了一个图片的最基本的属性。包括id号,格式定义等。刚刚开始的时候我不明白为什么id不定义成枚举类型,而要定义成int。当我看到下面的代码的时候,我知道了。
我们接着看下面的代码
jas_init
/*Initializetheimageformattable.*/
intjas_init()
{
jas_image_fmtops_tfmtops;
intfmtid;
fmtid=0;
#if!defined(EXCLUDE_MIF_SUPPORT)
fmtops.decode=mif_decode;
fmtops.encode=mif_encode;
fmtops.validate=mif_validate;
jas_image_addfmt(fmtid,"mif","mif","MyImageFormat(MIF)",&fmtops);
++fmtid;
#endif
#if!defined(EXCLUDE_PNM_SUPPORT)
fmtops.decode=pnm_decode;
fmtops.encode=pnm_encode;
fmtops.validate=pnm_validate;
jas_image_addfmt(fmtid,"pnm","pnm","PortableGraymap/Pixmap(PNM)",
&fmtops);
jas_image_addfmt(fmtid,"pnm","pgm","PortableGraymap/Pixmap(PNM)",
&fmtops);
jas_image_addfmt(fmtid,"pnm","ppm","PortableGraymap/Pixmap(PNM)",
&fmtops);
++fmtid;
#endif
#if!defined(EXCLUDE_BMP_SUPPORT)
fmtops.decode=bmp_decode;
fmtops.encode=bmp_encode;
fmtops.validate=bmp_validate;
jas_image_addfmt(fmtid,"bmp","bmp","MicrosoftBitmap(BMP)",&fmtops);
++fmtid;
#endif
#if!defined(EXCLUDE_RAS_SUPPORT)
fmtops.decode=ras_decode;
fmtops.encode=ras_encode;
fmtops.validate=ras_validate;
jas_image_addfmt(fmtid,"ras","ras","SunRasterfile(RAS)",&fmtops);
++fmtid;
#endif
#if!defined(EXCLUDE_JP2_SUPPORT)
fmtops.decode=jp2_decode;
fmtops.encode=jp2_encode;
fmtops.validate=jp2_validate;
jas_image_addfmt(fmtid,"jp2","jp2",
"JPEG-2000JP2FileFormatSyntax(ISO/IEC15444-1)",&fmtops);
++fmtid;
fmtops.decode=jpc_decode;
fmtops.encode=jpc_encode;
fmtops.validate=jpc_validate;
jas_image_addfmt(fmtid,"jpc","jpc",
"JPEG-2000CodeStreamSyntax(ISO/IEC15444-1)",&fmtops);
++fmtid;
#endif
#if!defined(EXCLUDE_JPG_SUPPORT)
fmtops.decode=jpg_decode;
fmtops.encode=jpg_encode;
fmtops.validate=jpg_validate;
jas_image_addfmt(fmtid,"jpg","jpg","JPEG(ISO/IEC10918-1)",&fmtops);
++fmtid;
#endif
#if!defined(EXCLUDE_PGX_SUPPORT)
fmtops.decode=pgx_decode;
fmtops.encode=pgx_encode;
fmtops.validate=pgx_validate;
jas_image_addfmt(fmtid,"pgx","pgx","JPEG-2000VMFormat(PGX)",&fmtops);
++fmtid;
#endif
/*WemustnotregistertheJasPerlibraryexithandleruntilafter
atleastonememoryallocationisperformed.Thisisdesirable
asitensuresthattheJasPerexithandleriscalledbeforethe
debugmemoryallocatorexithandler.*/
atexit(jas_cleanup);
return0;
}
intjas_image_addfmt(intid,char*name,char*ext,char*desc,
jas_image_fmtops_t*ops)
{
jas_image_fmtinfo_t*fmtinfo;
assert(id>=0&&name&&ext&&ops);
if(jas_image_numfmts>=JAS_IMAGE_MAXFMTS){
return-1;
}
fmtinfo=&jas_image_fmtinfos[jas_image_numfmts];
fmtinfo->id=id;
if(!(fmtinfo->name=jas_strdup(name))){
return-1;
}
if(!(fmtinfo->ext=jas_strdup(ext))){
jas_free(fmtinfo->name);
return-1;
}
if(!(fmtinfo->desc=jas_strdup(desc))){
jas_free(fmtinfo->name);
jas_free(fmtinfo->ext);
return-1;
}
fmtinfo->ops=*ops;
++jas_image_numfmts;
return0;
}
jas_image_fmtinfos是jas_image_fmtinfo_t类型的数组。
答案即将揭晓:
从上面的代码可以看出,作者使用了表格驱动编程。全局变量jas_image_fmtinfos保存了所有支持的图片格式的全部信息。而每次要对某种格式进行添加或者删除的时候,只用修改jas_init的代码就可以了,而且格式的编号是动态的。每次进行使用的时候去该数组中查找就可以了。
下面看看使用的代码,这段函数是根据后缀名查询编号的。
intjas_image_fmtfromname(char*name)
intjas_image_fmtfromname(char*name)
{
inti;
char*ext;
jas_image_fmtinfo_t*fmtinfo;
/*Getthefilenameextension.*/
if(!(ext=strrchr(name,'.'))){
return-1;
}
++ext;
/*Trytofindaformatthatusesthisextension.*/
for(i=0,fmtinfo=jas_image_fmtinfos;i<jas_image_numfmts;++i,
++fmtinfo){
/*Dowehaveamatch?*/
if(!strcmp(ext,fmtinfo->ext)){
returnfmtinfo->id;
}
}
return-1;
}
从上面的代码可以看出,每次查询后缀对应的格式的时候,去比较当前的后缀名和jas_image_fmtinfos数组中对应的后缀名,来确定id好,扩展性极好。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理