您的位置:首页 > 编程语言

编程技巧之表格驱动编程

2014-07-27 20:33 183 查看
/*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好,扩展性极好。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: