How to Use libpng and libjpeg to read from files and read from memory 2

Source: Internet
Author: User
Tags pngimage

Recently, libpng and libjpeg have been used in our work to parse images. We need to parse RGB data, provide 8-bit and 24-bit 2 excuses, and scale images, I have written my own code based on my articles from various friends on the Internet, and I am posting it for your reference.

1. read from a file:

Bool pngimage: loadfromfile (const char * path, image_type type)
{
// Re-Initialize to prevent loading multiple images.
M_good = false;
M_width = 0;
M_height = 0;
If (m_bgra)
{
Delete m_bgra; m_bgra = 0; // class member variable, which stores 24-bit RGB data.
}
If (m_8bit)
{
Delete m_8bit; m_8bit = 0; // class member variable, which stores 8-bit data.
}

If (type = image_png)
{

// Parse PNG files

// Try to open file
File * file = fopen (path, "rb ");

// Unable to open
If (file = 0) return false;

// Create read struct
Png_structp png_ptr = png_create_read_struct (png_libpng_ver_string, 0, 0, 0 );

// Check pointer
If (png_ptr = 0)
{
Fclose (File );
Return false;
}

// Create info struct
Png_infop info_ptr = png_create_info_struct (png_ptr );

// Check pointer
If (info_ptr = 0)
{
Png_destroy_read_struct (& png_ptr, 0, 0 );
Fclose (File );
Return false;
}

// Set error handling
If (setjmp (png_jmpbuf (png_ptr )))
{
Png_destroy_read_struct (& png_ptr, & info_ptr, 0 );
Fclose (File );
Return false;
}

// I/O initialization using standard C streams
Png_init_io (png_ptr, file );

// Read entire image, ignore alpha channel. If you want to use alpha channel, remove png_transform_strip_alpha.
Png_read_png (png_ptr, info_ptr, png_transform_expand | png_transform_strip_alpha, 0 );
/*
Png_transform_expand has the following processing:
1. Expand paletted colors into true RGB triplets
2. Expand grayscale images to full 8 bits from 1, 2, or 4 bits/Pixel
3. Expand paletted or RGB Images with transparency to Full Alpha channels so the data will be available
As rgba quartets.

Png_transform_strip_alpha: Strip Alpha bytes from the input data without combining withthe background
*/

Int width = m_width = info_ptr-> width;
Int Height = m_height = info_ptr-> height;
Int color_type = info_ptr-> color_type;
Int bit_depth = info_ptr-> pixel_depth;

Png_bytep * row_pointers = png_get_rows (png_ptr, info_ptr );

Int Pos = 0;

If (color_type = png_color_type_gray)
{// Grayscale image processing
M_8bit = new unsigned char [width * Height];
Memset (m_8bit, 0, width * Height );
For (INT I = 0; I {
For (Int J = 0; j <width; j + = 1)
{
M_8bit [POS ++] = row_pointers [I] [J];
}
}
}
Else
{// Process non-Grayscale Images
M_bgra = new unsigned char [width * height * 3];
Memset (m_bgra, 0, width * height * 3 );
For (INT I = 0; I {
For (Int J = 0; j <3 * width; j + = 3)
{
M_bgra [POS ++] = row_pointers [I] [J + 2]; // blue
M_bgra [POS ++] = row_pointers [I] [J + 1]; // green
M_bgra [POS ++] = row_pointers [I] [J]; // red
}
}
}

// Free memory
Png_destroy_read_struct (& png_ptr, & info_ptr, 0 );

// Close file
Fclose (File );

}
Else if (type = image_jpeg)
{// Parse JPEG images
Struct performance_decompress_struct Cinfo;
Struct performance_error_mgr Jerr;

Cinfo. Err = maid (& Jerr );
Pai_create_decompress (& Cinfo );

File * infile;
If (infile = fopen (path, "rb") = NULL)
{
Printf ("Open File error! /N ");
Return false;
}

Performance_stdio_src (& Cinfo, infile );

Pai_read_header (& Cinfo, true );
M_height = Cinfo. image_height;
M_width = Cinfo. image_width;

M_bgra = new unsigned char [Cinfo. image_width * Cinfo. image_height * Cinfo. num_components];

Pai_start_decompress (& Cinfo );

Jsamprow row_pointer [1];

While (Cinfo. output_scanline <Cinfo. output_height)
{
/* Row_pointer [0] = & m_bgr [(Cinfo. output_height-cinfo.output_scanline-1)
* Cinfo. image_width * Cinfo. num_components]; */
Row_pointer [0] = & m_bgra [Cinfo. output_scanline * Cinfo. image_width * Cinfo. num_components];
Pai_read_scanlines (& Cinfo, row_pointer, 1 );
}

Pai_finish_decompress (& Cinfo );
Pai_destroy_decompress (& Cinfo );

Fclose (infile );
}

Return true;
}

 

2. Read from memory:

For PNG format, you need to reset the read callback function for reading from memory, and then use the png_set_read_fn () function to specify the READ function.

For JPEG format, you only need to use the pai_mem_src () function to replace the original jpeg_stdio_src (& Cinfo, infile) read from the file.

 

Typedef struct
{
Unsigned char * data;
Int size;
Int offset;
} Imagesource;

 

// Callback function for reading PNG images from memory

Static void pngreadcallback (png_structp png_ptr, png_bytep data, png_size_t length)
{
Imagesource * isource = (imagesource *) png_get_io_ptr (png_ptr );

If (isource-> Offset + Length <= isource-> size)
{
Memcpy (data, isource-> Data + isource-> offset, length );
Isource-> Offset + = length;
}
Else
Png_error (png_ptr, "pngreadercallback failed ");
}

 

// Read from memory

Bool pngimage: loadfromstream (unsigned char * data, const unsigned int datasize, image_type type)
{
M_good = false;
M_width = 0;
M_height = 0;
If (m_bgra)
{
Delete m_bgra; m_bgra = 0;
}
If (m_8bit)
{
Delete m_8bit; m_8bit = 0;
}

If (type = image_png)
{

Png_structp png_ptr = png_create_read_struct (png_libpng_ver_string, 0, 0, 0 );
If (png_ptr = 0)
Return false;

Png_infop info_ptr = png_create_info_struct (png_ptr );
If (info_ptr = 0)
{
Png_destroy_read_struct (& png_ptr, 0, 0 );
Return false;
}

If (setjmp (png_jmpbuf (png_ptr )))
{
Png_destroy_read_struct (& png_ptr, & info_ptr, 0 );
}

Imagesource imgsource;
Imgsource. Data = data;
Imgsource. size = datasize;
Imgsource. offset = 0;
Png_set_read_fn (png_ptr, & imgsource, pngreadcallback );

Png_read_png (png_ptr, info_ptr, png_transform_expand | png_transform_strip_alpha, 0 );

Int width = m_width = info_ptr-> width;
Int Height = m_height = info_ptr-> height;
Int color_type = info_ptr-> color_type;
Int bit_depth = info_ptr-> pixel_depth;

Png_bytep * row_pointers = png_get_rows (png_ptr, info_ptr );

Int Pos = 0;

If (color_type = png_color_type_gray)
{
M_8bit = new unsigned char [width * Height];
Memset (m_8bit, 0, width * Height );
For (INT I = 0; I {
For (Int J = 0; j <width; j + = 1)
{
M_8bit [POS ++] = row_pointers [I] [J];
}
}
}
Else
{
M_bgra = new unsigned char [width * height * 3];
Memset (m_bgra, 0, width * height * 3 );
For (INT I = 0; I {
For (Int J = 0; j <3 * width; j + = 3)
{
M_bgra [POS ++] = row_pointers [I] [J + 2]; // blue
M_bgra [POS ++] = row_pointers [I] [J + 1]; // green
M_bgra [POS ++] = row_pointers [I] [J]; // red
}
}
}

// Free memory
Png_destroy_read_struct (& png_ptr, & info_ptr, 0 );
}
Else if (type = image_jpeg)
{
Struct performance_decompress_struct Cinfo;
Struct performance_error_mgr Jerr;

Cinfo. Err = maid (& Jerr );
Pai_create_decompress (& Cinfo );

// Read from memory
Performance_mem_src (& Cinfo, Data, datasize );

Pai_read_header (& Cinfo, true );
M_height = Cinfo. image_height;
M_width = Cinfo. image_width;

M_bgra = new unsigned char [Cinfo. image_width * Cinfo. image_height * Cinfo. num_components];

Pai_start_decompress (& Cinfo );

Jsamprow row_pointer [1];

While (Cinfo. output_scanline <Cinfo. output_height)
{
/* Row_pointer [0] = & m_bgr [(Cinfo. output_height-cinfo.output_scanline-1)
* Cinfo. image_width * Cinfo. num_components]; */
Row_pointer [0] = & m_bgra [Cinfo. output_scanline * Cinfo. image_width * Cinfo. num_components];
Pai_read_scanlines (& Cinfo, row_pointer, 1 );
}

Pai_finish_decompress (& Cinfo );
Pai_destroy_decompress (& Cinfo );
}
 
Return/* (m_good = true) */true;
}

 

3. Scaling images is a widely spread interpolation algorithm on the Internet.

The input parameter is: return the image width (w_dest), return the Image Height (h_dest), return the image depth (bit_depth), and the source image RGB data (SRC ), the source image width (w_src) and the source Image Height (h_src ).

Unsigned char * pngimage: do_stretch_linear (INT w_dest, int h_dest, int bit_depth, unsigned char * SRC, int w_src, int h_src)
{
Int Sw = w_Src-1, SH = h_Src-1, DW = w_Dest-1, DH = h_Dest-1;
Int B, n, x, y;
Int npixelsize = bit_depth/8;
Unsigned char * plineprev, * plinenext;
Unsigned char * pdest = new unsigned char [w_dest * h_dest * bit_depth/8];
Unsigned char * TMP;
Unsigned char * pA, * pb, * PC, * PD;
 
For (INT I = 0; I <= DH; ++ I)
{
TMP = pdest + I * w_dest * npixelsize;
Y = I * sh/DH;
N = DH-I * sh % DH;
Plineprev = SRC + (Y ++) * w_src * npixelsize;
// Plineprev = (unsigned char *) asrc-> m_bitbuf + (Y ++) * asrc-> m_width * npixelsize );
Plinenext = (n = DH )? Plineprev: SRC + y * w_src * npixelsize;
// Plinenext = (n = DH )? Plineprev: (unsigned char *) asrc-> m_bitbuf + (y * asrc-> m_width * npixelsize );
For (Int J = 0; j <= dw; ++ J)
{
X = J * Sw/DW * npixelsize;
B = DW-J * SW % dw;
Pa = plineprev + X;
PB = pa + npixelsize;
PC = plinenext + X;
Pd = PC + npixelsize;
If (B = DW)
{
PB = PA;
Pd = pc;
}

For (int K = 0; k <npixelsize; ++ K)
{
* TMP ++ = (unsigned char) (INT )(
(B * n * (* pA ++-* pb-* PC + * PD) + DW * n ** Pb ++
+ DH * B ** PC ++ (DW * DH-DH * B-DW * n) ** PD ++
+ DW * DH/2)/(DW * DH ));
}
}
}
Return pdest;
}

 

If you find any imperfections, you are welcome to discuss them.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.