编程技巧之表格驱动编程
生活随笔
收集整理的這篇文章主要介紹了
编程技巧之表格驱动编程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
/* Image format-dependent operations. */
typedef struct {
jas_image_t *(*decode)(jas_stream_t *in, char *opts);
/* Decode image data from a stream. */
int (*encode)(jas_image_t *image, jas_stream_t *out, char *opts);
/* Encode image data to a stream. */
int (*validate)(jas_stream_t *in);
/* Determine if stream data is in a particular format. */
} jas_image_fmtops_t;
/* Image format information. */
typedef struct {
int id;
/* The ID for this format. */
char *name;
/* The name by which this format is identified. */
char *ext;
/* The file name extension associated with this format. */
char *desc;
/* A brief description of the format. */
jas_image_fmtops_t ops;
/* The operations for this format. */
} jas_image_fmtinfo_t;
這段代碼是從jasper的源代碼中摘抄出來的,jas_image_fmtops_t 這個結構體定義了三個函數指針,是對圖像的基本操作。s_image_fmtinfo_t 描述了一個圖片的最基本的屬性。包括id號,格式定義等。剛剛開始的時候我不明白為什么id不定義成枚舉類型,而要定義成int。當我看到下面的代碼的時候,我知道了。
我們接著看下面的代碼
jas_init
/* Initialize the image format table. */
int jas_init()
{
jas_image_fmtops_t fmtops;
int fmtid;
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", "My Image Format (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", "Portable Graymap/Pixmap (PNM)",
&fmtops);
jas_image_addfmt(fmtid, "pnm", "pgm", "Portable Graymap/Pixmap (PNM)",
&fmtops);
jas_image_addfmt(fmtid, "pnm", "ppm", "Portable Graymap/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", "Microsoft Bitmap (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", "Sun Rasterfile (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-2000 JP2 File Format Syntax (ISO/IEC 15444-1)", &fmtops);
++fmtid;
fmtops.decode = jpc_decode;
fmtops.encode = jpc_encode;
fmtops.validate = jpc_validate;
jas_image_addfmt(fmtid, "jpc", "jpc",
"JPEG-2000 Code Stream Syntax (ISO/IEC 15444-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/IEC 10918-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-2000 VM Format (PGX)", &fmtops);
++fmtid;
#endif
/* We must not register the JasPer library exit handler until after
at least one memory allocation is performed. This is desirable
as it ensures that the JasPer exit handler is called before the
debug memory allocator exit handler. */
atexit(jas_cleanup);
return 0;
}
int jas_image_addfmt(int id, 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;
return 0;
}
jas_image_fmtinfos 是jas_image_fmtinfo_t類型的數組。
答案即將揭曉:
從上面的代碼可以看出,作者使用了表格驅動編程。全局變量jas_image_fmtinfos 保存了所有支持的圖片格式的全部信息。而每次要對某種格式進行添加或者刪除的時候,只用修改jas_init的代碼就可以了,而且格式的編號是動態的。每次進行使用的時候去該數組中查找就可以了。
下面看看使用的代碼,這段函數是根據后綴名查詢編號的。
int jas_image_fmtfromname(char *name)
int jas_image_fmtfromname(char *name)
{
int i;
char *ext;
jas_image_fmtinfo_t *fmtinfo;
/* Get the file name extension. */
if (!(ext = strrchr(name, '.'))) {
return -1;
}
++ext;
/* Try to find a format that uses this extension. */
for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i,
++fmtinfo) {
/* Do we have a match? */
if (!strcmp(ext, fmtinfo->ext)) {
return fmtinfo->id;
}
}
return -1;
}
從上面的代碼可以看出,每次查詢后綴對應的格式的時候,去比較當前的后綴名和jas_image_fmtinfos 數組中對應的后綴名,來確定id好,擴展性極好。
總結
以上是生活随笔為你收集整理的编程技巧之表格驱动编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: es面试题
- 下一篇: 怎么创建具有真实纹理的CG场景岩石?