Examples include libgif, LibPNG, and libjpeg. Image types are judged as follows. fdata is the first address of image data.
// PNG
If (! Png_sig_cmp (png_byte *) fdata, (png_size_t) 0, 4 ))
{
Return en_img_tyie_png;
}
// GIF
If (memcmp (gif_stamp, fdata, gif_stamp_len) = 0 |
Memcmp (gif87_stamp, fdata, gif_stamp_len) = 0 |
Memcmp (gif89_stamp, fdata, gif_stamp_len) = 0)
{
Return en_img_tyie_gif;
}
// JPG
Char gheader [] = {0xff, 0xd8, 0xff };
If (memcmp (fdata, gheader, 3) = 0)
{
Return en_img_tyie_jpg;
}
// BMP
Char kbmp magic [] = {'B', 'M '};
If (memcmp (fdata, kbmp magic, 2) = 0)
{
Return en_img_tyie_bmp;
}
Return en_img_type_none;
Parse PNG Code as follows: fdata is PNG image data, fsize is the data length, width and height are the output parameters, store the width and height of the image, and return the image data in rgba format.
Unsigned char * bwimagedecode: decodememorypng (unsigned char * fdata, long fsize, Int & width, Int & height)
{
Png_structp png_ptr;
Png_infop info_ptr;
Int bit_depth, color_type;
Png_bytep * row_pointers = NULL;
Unsigned char * image_data;
Int rowbytes;
/* Create a PNG read struct */
Png_ptr = png_create_read_struct (png_libpng_ver_string, null, null );
If (! Png_ptr)
{
Return NULL;
}
/* Create a PNG info struct */
Info_ptr = png_create_info_struct (png_ptr );
If (! Info_ptr)
{
Png_destroy_read_struct (& png_ptr, null, null );
Return NULL;
}
/* Initialize the setjmp for returning properly after a libpng error occured */
If (setjmp (png_jmpbuf (png_ptr )))
{
Png_destroy_read_struct (& png_ptr, & info_ptr, null );
If (row_pointers)
Free (row_pointers );
Return NULL;
}
Imagesource imgsource;
Imgsource. Data = fdata;
Imgsource. size = fsize;
Imgsource. offset = 0;
Png_set_read_fn (png_ptr, & imgsource, memreadfuncpng );
/* Read PNG info */
Png_read_info (png_ptr, info_ptr );
/* Get Some usefull information from header */
Bit_depth = png_get_bit_depth (png_ptr, info_ptr );
Color_type = png_get_color_type (png_ptr, info_ptr );
/* Convert index color images to RGB Images */
If (color_type = png_color_type_palette)
Png_set_palette_to_rgb (png_ptr );
/* Convert RGB Images to rgba images */
If (color_type = png_color_type_rgb)
Png_set_filler (png_ptr, 0xff, png_filler_after );
/* Convert 1-2-4 bits grayscale images to 8 bits grayscale .*/
If (color_type = png_color_type_gray & bit_depth <8)
Png_set_gray_1_2_4_to_8 (png_ptr );
If (png_get_valid (png_ptr, info_ptr, png_info_trns ))
Png_set_trns_to_alpha (png_ptr );
If (bit_depth = 16)
Png_set_strip_16 (png_ptr );
Else if (bit_depth <8)
Png_set_packing (png_ptr );
/* Update INFO structure to apply transformations */
Png_read_update_info (png_ptr, info_ptr );
/* Retrieve updated information */
Png_get_ihdr (png_ptr, info_ptr, (png_uint_32 *) & width, (png_uint_32 *) & height, & bit_depth, & color_type, null, null );
Rowbytes = png_get_rowbytes (png_ptr, info_ptr );
If (image_data = (unsigned char *) malloc (height * rowbytes) = NULL)
{
Png_destroy_read_struct (& png_ptr, & info_ptr, null );
Return NULL;
}
/* Setup a pointer array. Each one points at the Begening of a row .*/
If (row_pointers = (png_bytepp) malloc (height * sizeof (png_bytep) = NULL)
{
Png_destroy_read_struct (& png_ptr, & info_ptr, null );
Free (image_data );
Return NULL;
}
For (INT I = 0; I Row_pointers [height-1-I] = image_data + I * rowbytes;
/* Read pixel data using row pointers */
Png_read_image (png_ptr, row_pointers );
/* Finish decompression and release memory */
Png_read_end (png_ptr, null );
Png_destroy_read_struct (& png_ptr, & info_ptr, null );
/* We Don't Need row pointers anymore */
Free (row_pointers );
Return image_data;
}
Parse the JPG Code as follows: fdata is jpg image data, fsize is the data length, width and height are the output parameters, store the width and height of the image, and return the image data in rgba format.
Unsigned char * bwimagedecode: decodememoryjpg (unsigned char * fdata, long fsize, Int & width, Int & height)
{
Unsigned char * image_data;
Struct performance_decompress_struct Cinfo;
Struct performance_error_mgr Jerr;
Unsigned char * buffer;
Int row_stride;
Int out_color_components = 4;
Cinfo. Err = maid (& Jerr );
Pai_create_decompress (& Cinfo );
// Read from memory
Performance_stdio_buffer_src (& Cinfo, fdata, fsize );
Pai_read_header (& Cinfo, true );
// Cinfo. out_color_components = 3;
// Cinfo. out_color_space = jcs_rgb;
Pai_start_decompress (& Cinfo );
Width = Cinfo. output_width;
Height = Cinfo. output_height;
Row_stride = Cinfo. output_width * Cinfo. output_components;
Buffer = (unsigned char *) malloc (row_stride );
Image_data = (unsigned char *) malloc (Cinfo. output_width * Cinfo. output_height * out_color_components );
While (Cinfo. output_scanline <Cinfo. output_height)
{
Unsigned char * P = image_data + (Cinfo. output_width * out_color_components * Cinfo. output_scanline );
Pai_read_scanlines (& Cinfo, & buffer, 1 );
For (INT I = 0; I <width; I ++)
{
P [4 * I] = buffer [3 * I];
P [4 * I + 1] = buffer [3 * I + 1];
P [4 * I + 2] = buffer [3 * I + 2];
P [4 * I + 3] = 0xff;
}
}
Pai_finish_decompress (& Cinfo );
Pai_destroy_decompress (& Cinfo );
Free (buffer );
Return image_data;
}
Parse the GIF Code as follows: fdata is the GIF image data, fsize is the data length, width and height are the output parameters, the width and height of the image are stored, and the index is the first frame, returns image data in rgba format.
Static int memreadfuncgif (giffiletype * giffile, gifbytetype * Buf, int count)
{
Char * PTR = (char *) (giffile-> userdata );
Memcpy (BUF, PTR, count );
Giffile-> userdata = PTR + count;
Return count;
}
Unsigned char * bwimagedecode: decodememorygif (unsigned char * fdata, long fsize, Int & width, Int & height, int index)
{
Giffiletype * giffile;
If (giffile = dgifopen (fdata, memreadfuncgif) = NULL)
{
Return 0;
}
If (dgifslurp (giffile) = 0)
{
Return 0;
}
Unsigned char * image_data = 0, * src = 0, * DST = 0;
Colormapobject * colormap;
Savedimage * saveimg;
Gifrowtype * screenbuffer;
Gifcolortype * colormapentry;
Int loc = 0;
If (index> = giffile-> imagecount)
{
Return 0;
}
// Index = index % giffile-> imagecount;
Colormap = (giffile-> image. colormap? Giffile-> image. colormap: giffile-> scolormap );
Saveimg = & (giffile-> savedimages [Index]);
Screenbuffer = & (saveimg-> rasterbits );
If (image_data = (unsigned char *) malloc (giffile-> swidth * 4 * giffile-> sheight) = NULL)
{
Dgifclosefile (giffile );
Return 0;
}
Src = saveimg-> rasterbits;
DST = image_data;
For (INT I = 0; I <giffile-> sheight; I ++)
{
Loc = giffile-> swidth * I;
For (Int J = 0; j <giffile-> swidth; j ++)
{
Colormapentry = & (colormap-> colors [* (SRC + loc + J)]);
* DST ++ = colormapentry-> red;
* DST ++ = colormapentry-> green;
* DST ++ = colormapentry-> blue;
* DST ++ = 255;
}
}
Width = giffile-> swidth;
Height = giffile-> sheight;
//{
// M_imagecount = giffile-> imagecount;
// M_imagewidth = giffile-> swidth;
// M_imageheight = giffile-> sheight;
// M_giffile = giffile;
// M_imagedata = image_data;
//}
Dgifclosefile (giffile );
Return image_data;
}
Void * bwimagedecode: decodememorygifimage (unsigned char * fdata, long fsize, Int & width, Int & height)
{
Giffiletype * giffile;
If (giffile = dgifopen (fdata, memreadfuncgif) = NULL)
{
Return 0;
}
If (dgifslurp (giffile) = 0)
{
Return 0;
}
Width = giffile-> swidth;
Height = giffile-> sheight;
Return giffile;
}
Unsigned char * bwimagedecode: getgifimage (void * giffile, int index)
{
If (giffile = 0) return 0;
Giffiletype * giffile = (giffiletype *) giffile;
Unsigned char * image_data = 0, * src = 0, * DST = 0;
Colormapobject * colormap;
Savedimage * saveimg;
Gifrowtype * screenbuffer;
Gifcolortype * colormapentry;
Int loc = 0;
If (index> = giffile-> imagecount)
{
Return 0;
}
Index = index % giffile-> imagecount;
Colormap = (giffile-> image. colormap? Giffile-> image. colormap: giffile-> scolormap );
Saveimg = & (giffile-> savedimages [Index]);
Screenbuffer = & (saveimg-> rasterbits );
If (image_data = (unsigned char *) malloc (giffile-> swidth * 4 * giffile-> sheight) = NULL)
{
Dgifclosefile (giffile );
Return 0;
}
Src = saveimg-> rasterbits;
DST = image_data;
For (INT I = 0; I <giffile-> sheight; I ++)
{
Loc = giffile-> swidth * I;
For (Int J = 0; j <giffile-> swidth; j ++)
{
Colormapentry = & (colormap-> colors [* (SRC + loc + J)]);
* DST ++ = colormapentry-> red;
* DST ++ = colormapentry-> green;
* DST ++ = colormapentry-> blue;
* DST ++ = 255;
}
}
// LogE ("getgifimage -- % d", image_data );
Return image_data;
}
Char * bwimagedecode: getgifduration (void * giffile)
{
If (giffile = 0) return 0;
Giffiletype * giffile = (giffiletype *) giffile;
Char * duration = (char *) malloc (giffile-> imagecount); // new char [giffile-> imagecount];
For (INT I = 0; I <giffile-> imagecount; I ++)
{
Duration [I] = savedimage_duration (& giffile-> savedimages [I]);
}
Return duration;
}
Int bwimagedecode: savedimage_duration (const savedimage * image)
{
For (Int J = 0; j <image-> extensionblockcount; j ++)
{
If (image-> extensionblocks [J]. Function = graphics_ext_func_code)
{
Int size = image-> extensionblocks [J]. bytecount;
Const uint8_t * B = (const uint8_t *) image-> extensionblocks [J]. bytes;
Return (B [2] <8) | B [1]) * 10;
}
}
Return 0;
}