Using libpng 1.2 to write RGB image buffer to PNG buffer in memory causing segmentation fault











up vote
0
down vote

favorite












My project need to receive a PNG file content over HTTP request, do something to the image and sending back the generated PNG back in the HTTP response. All code need to be done in C/C++.



I'm new to libpng. So I try to write a prototype, reading a PNG file into unsigned char buffer, get the RGB values out (ignore alpha), do no-op, create a new unsigned char buffer with PNG file content, write the new file to the disk and validate I "generate" the same image. I have referenced this question in StackOverflow



My code (with some unrelated function removed, full runnable code is here):



#include <iostream>
#include <fstream>
#include <string>
#include <vector>

#include <png.h>

using namespace std;

typedef struct
{
png_bytep data;
int size;
} ImageTarget;

int read_png(string file_path, unsigned char** buffer)
{
// ... ...
}

void write_png(string file_path, unsigned char* buffer, int length)
{
// ... ...
}

static void pngReadCallback(png_structp png_ptr, png_bytep data, png_size_t length)
{
// ... ...
}

void pngWriteCallback(png_structp png_ptr, png_bytep data, png_size_t length)
{
cout << "- length ----------- " << length << endl;
ImageTarget * itarget = (ImageTarget*)png_get_io_ptr(png_ptr);
size_t nsize = itarget->size + length;
cout << "- nsize ----------- " << nsize << endl;
cout << "- data ------ " << (size_t) itarget->data << endl;

if(itarget->data != nullptr)
itarget->data = (unsigned char*)realloc(itarget->data, nsize);
else
itarget->data = (unsigned char*)malloc(nsize);

memcpy(itarget->data + itarget->size, data, length);
itarget->size += length;
}

int main()
{
const string Input_PNG = "pic/c.png";
const string Output_PNG = "output/output.png";

unsigned char* buffer = nullptr;
int length = read_png(Input_PNG, &buffer);

png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
png_infop info_ptr = png_create_info_struct(png_ptr);

ImageSource imgsource;
imgsource.data = buffer;
imgsource.size = length;
imgsource.offset = 0;
png_set_read_fn(png_ptr, &imgsource, pngReadCallback);

png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_ALPHA, 0);
int w = png_get_image_width( png_ptr, info_ptr );
int h = png_get_image_height( png_ptr, info_ptr );

cout << "Image width (from PNG file): " << w << endl;
cout << "Image height (from PNG file): " << h << endl;

png_bytep* row_pointers = png_get_rows( png_ptr, info_ptr );
png_bytep raw_rgb = (png_bytep)malloc(w * h * 3);
int i = 0;
for(int y=0; y<h; ++y ) {
for(int x=0; x<w*3; ) {
raw_rgb[i++] = row_pointers[y][x++]; // red
raw_rgb[i++] = row_pointers[y][x++]; // green
raw_rgb[i++] = row_pointers[y][x++]; // blue
}
}

// Do Something

png_destroy_read_struct( &png_ptr, &info_ptr, 0);

// ---------------------------------

png_structp wpng_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_infop winfo_ptr = png_create_info_struct(wpng_ptr);
setjmp(png_jmpbuf(wpng_ptr));

png_set_IHDR(wpng_ptr, winfo_ptr, 720, 720, 8,
PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
png_set_rows(wpng_ptr, winfo_ptr, &raw_rgb);

ImageTarget itarget;
itarget.data = nullptr;
itarget.size = 0;
png_set_write_fn(wpng_ptr, &itarget, pngWriteCallback, NULL);

png_write_png(wpng_ptr, winfo_ptr, PNG_TRANSFORM_IDENTITY, NULL);

cout << "Output file name: " << Output_PNG << endl;
write_png(Output_PNG, itarget.data, length);
return 0;
}


The makefile I use: here.



After compile and run my code, I see the output (I have verified the c.png I used is a PNG file by Irfanview):



Image width (from PNG file): 720
Image height (from PNG file): 720
- length ----------- 8
- nsize ----------- 8
- data ------ 0
- length ----------- 8
- nsize ----------- 16
- data ------ 22161152
- length ----------- 13
- nsize ----------- 29
- data ------ 22161152
- length ----------- 4
- nsize ----------- 33
- data ------ 22161152
[1] 6675 segmentation fault (core dumped) ./png_from_buffer


Check the core file with gdb, here is the output:



#0  __memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:35
#1 0x00007f3c41b3caf0 in png_write_row () from /lib/x86_64-linux-gnu/libpng12.so.0
#2 0x00007f3c41b3cd78 in png_write_image () from /lib/x86_64-linux-gnu/libpng12.so.0
#3 0x00007f3c41b3d61b in png_write_png () from /lib/x86_64-linux-gnu/libpng12.so.0
#4 0x000000000040269c in main () at main.cpp:181


I tried using different buffer, convert to vector<unsigned char*> as the rows. No luck so far. Any idea will be appreciated.



My environment, if matters:




  • Ubuntu 16.04

  • libpng 1.2


    • libpng12-0/xenial-updates,xenial-security,now 1.2.54-1ubuntu1.1 amd64 [installed]

    • libpng12-dev/xenial-updates,xenial-security,now 1.2.54-1ubuntu1.1 amd64 [installed,automatic]



  • g++ (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609










share|improve this question




















  • 3




    Minimal, Complete, and Verifiable example or it didn't happen.
    – Swordfish
    Nov 10 at 8:02










  • Thank you @Swordfish! I do have a compilable cpp file and makefile in the link. They are too long and I do not want to make this post contain the full content. Could you please try click on the link and help me taking a look? Thanks!
    – NonStatic
    Nov 10 at 8:04










  • @NonStatic Example needs to be Minimal to fit into the post. Actually the posted snippet is full of dangerous raw pointer juggling and wild casts. You should probably fix all that stuff because it is the third most common reason of program bugs.
    – VTT
    Nov 10 at 8:08












  • This is just a prototype to learn/understand libpng APIs. I will definitely not using those raw pointers in my product code.
    – NonStatic
    Nov 10 at 8:10










  • please, go and write up a Minimal, Complete, and Verifiable example that shows the behaviour you have a question about.
    – Swordfish
    Nov 10 at 8:11















up vote
0
down vote

favorite












My project need to receive a PNG file content over HTTP request, do something to the image and sending back the generated PNG back in the HTTP response. All code need to be done in C/C++.



I'm new to libpng. So I try to write a prototype, reading a PNG file into unsigned char buffer, get the RGB values out (ignore alpha), do no-op, create a new unsigned char buffer with PNG file content, write the new file to the disk and validate I "generate" the same image. I have referenced this question in StackOverflow



My code (with some unrelated function removed, full runnable code is here):



#include <iostream>
#include <fstream>
#include <string>
#include <vector>

#include <png.h>

using namespace std;

typedef struct
{
png_bytep data;
int size;
} ImageTarget;

int read_png(string file_path, unsigned char** buffer)
{
// ... ...
}

void write_png(string file_path, unsigned char* buffer, int length)
{
// ... ...
}

static void pngReadCallback(png_structp png_ptr, png_bytep data, png_size_t length)
{
// ... ...
}

void pngWriteCallback(png_structp png_ptr, png_bytep data, png_size_t length)
{
cout << "- length ----------- " << length << endl;
ImageTarget * itarget = (ImageTarget*)png_get_io_ptr(png_ptr);
size_t nsize = itarget->size + length;
cout << "- nsize ----------- " << nsize << endl;
cout << "- data ------ " << (size_t) itarget->data << endl;

if(itarget->data != nullptr)
itarget->data = (unsigned char*)realloc(itarget->data, nsize);
else
itarget->data = (unsigned char*)malloc(nsize);

memcpy(itarget->data + itarget->size, data, length);
itarget->size += length;
}

int main()
{
const string Input_PNG = "pic/c.png";
const string Output_PNG = "output/output.png";

unsigned char* buffer = nullptr;
int length = read_png(Input_PNG, &buffer);

png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
png_infop info_ptr = png_create_info_struct(png_ptr);

ImageSource imgsource;
imgsource.data = buffer;
imgsource.size = length;
imgsource.offset = 0;
png_set_read_fn(png_ptr, &imgsource, pngReadCallback);

png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_ALPHA, 0);
int w = png_get_image_width( png_ptr, info_ptr );
int h = png_get_image_height( png_ptr, info_ptr );

cout << "Image width (from PNG file): " << w << endl;
cout << "Image height (from PNG file): " << h << endl;

png_bytep* row_pointers = png_get_rows( png_ptr, info_ptr );
png_bytep raw_rgb = (png_bytep)malloc(w * h * 3);
int i = 0;
for(int y=0; y<h; ++y ) {
for(int x=0; x<w*3; ) {
raw_rgb[i++] = row_pointers[y][x++]; // red
raw_rgb[i++] = row_pointers[y][x++]; // green
raw_rgb[i++] = row_pointers[y][x++]; // blue
}
}

// Do Something

png_destroy_read_struct( &png_ptr, &info_ptr, 0);

// ---------------------------------

png_structp wpng_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_infop winfo_ptr = png_create_info_struct(wpng_ptr);
setjmp(png_jmpbuf(wpng_ptr));

png_set_IHDR(wpng_ptr, winfo_ptr, 720, 720, 8,
PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
png_set_rows(wpng_ptr, winfo_ptr, &raw_rgb);

ImageTarget itarget;
itarget.data = nullptr;
itarget.size = 0;
png_set_write_fn(wpng_ptr, &itarget, pngWriteCallback, NULL);

png_write_png(wpng_ptr, winfo_ptr, PNG_TRANSFORM_IDENTITY, NULL);

cout << "Output file name: " << Output_PNG << endl;
write_png(Output_PNG, itarget.data, length);
return 0;
}


The makefile I use: here.



After compile and run my code, I see the output (I have verified the c.png I used is a PNG file by Irfanview):



Image width (from PNG file): 720
Image height (from PNG file): 720
- length ----------- 8
- nsize ----------- 8
- data ------ 0
- length ----------- 8
- nsize ----------- 16
- data ------ 22161152
- length ----------- 13
- nsize ----------- 29
- data ------ 22161152
- length ----------- 4
- nsize ----------- 33
- data ------ 22161152
[1] 6675 segmentation fault (core dumped) ./png_from_buffer


Check the core file with gdb, here is the output:



#0  __memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:35
#1 0x00007f3c41b3caf0 in png_write_row () from /lib/x86_64-linux-gnu/libpng12.so.0
#2 0x00007f3c41b3cd78 in png_write_image () from /lib/x86_64-linux-gnu/libpng12.so.0
#3 0x00007f3c41b3d61b in png_write_png () from /lib/x86_64-linux-gnu/libpng12.so.0
#4 0x000000000040269c in main () at main.cpp:181


I tried using different buffer, convert to vector<unsigned char*> as the rows. No luck so far. Any idea will be appreciated.



My environment, if matters:




  • Ubuntu 16.04

  • libpng 1.2


    • libpng12-0/xenial-updates,xenial-security,now 1.2.54-1ubuntu1.1 amd64 [installed]

    • libpng12-dev/xenial-updates,xenial-security,now 1.2.54-1ubuntu1.1 amd64 [installed,automatic]



  • g++ (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609










share|improve this question




















  • 3




    Minimal, Complete, and Verifiable example or it didn't happen.
    – Swordfish
    Nov 10 at 8:02










  • Thank you @Swordfish! I do have a compilable cpp file and makefile in the link. They are too long and I do not want to make this post contain the full content. Could you please try click on the link and help me taking a look? Thanks!
    – NonStatic
    Nov 10 at 8:04










  • @NonStatic Example needs to be Minimal to fit into the post. Actually the posted snippet is full of dangerous raw pointer juggling and wild casts. You should probably fix all that stuff because it is the third most common reason of program bugs.
    – VTT
    Nov 10 at 8:08












  • This is just a prototype to learn/understand libpng APIs. I will definitely not using those raw pointers in my product code.
    – NonStatic
    Nov 10 at 8:10










  • please, go and write up a Minimal, Complete, and Verifiable example that shows the behaviour you have a question about.
    – Swordfish
    Nov 10 at 8:11













up vote
0
down vote

favorite









up vote
0
down vote

favorite











My project need to receive a PNG file content over HTTP request, do something to the image and sending back the generated PNG back in the HTTP response. All code need to be done in C/C++.



I'm new to libpng. So I try to write a prototype, reading a PNG file into unsigned char buffer, get the RGB values out (ignore alpha), do no-op, create a new unsigned char buffer with PNG file content, write the new file to the disk and validate I "generate" the same image. I have referenced this question in StackOverflow



My code (with some unrelated function removed, full runnable code is here):



#include <iostream>
#include <fstream>
#include <string>
#include <vector>

#include <png.h>

using namespace std;

typedef struct
{
png_bytep data;
int size;
} ImageTarget;

int read_png(string file_path, unsigned char** buffer)
{
// ... ...
}

void write_png(string file_path, unsigned char* buffer, int length)
{
// ... ...
}

static void pngReadCallback(png_structp png_ptr, png_bytep data, png_size_t length)
{
// ... ...
}

void pngWriteCallback(png_structp png_ptr, png_bytep data, png_size_t length)
{
cout << "- length ----------- " << length << endl;
ImageTarget * itarget = (ImageTarget*)png_get_io_ptr(png_ptr);
size_t nsize = itarget->size + length;
cout << "- nsize ----------- " << nsize << endl;
cout << "- data ------ " << (size_t) itarget->data << endl;

if(itarget->data != nullptr)
itarget->data = (unsigned char*)realloc(itarget->data, nsize);
else
itarget->data = (unsigned char*)malloc(nsize);

memcpy(itarget->data + itarget->size, data, length);
itarget->size += length;
}

int main()
{
const string Input_PNG = "pic/c.png";
const string Output_PNG = "output/output.png";

unsigned char* buffer = nullptr;
int length = read_png(Input_PNG, &buffer);

png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
png_infop info_ptr = png_create_info_struct(png_ptr);

ImageSource imgsource;
imgsource.data = buffer;
imgsource.size = length;
imgsource.offset = 0;
png_set_read_fn(png_ptr, &imgsource, pngReadCallback);

png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_ALPHA, 0);
int w = png_get_image_width( png_ptr, info_ptr );
int h = png_get_image_height( png_ptr, info_ptr );

cout << "Image width (from PNG file): " << w << endl;
cout << "Image height (from PNG file): " << h << endl;

png_bytep* row_pointers = png_get_rows( png_ptr, info_ptr );
png_bytep raw_rgb = (png_bytep)malloc(w * h * 3);
int i = 0;
for(int y=0; y<h; ++y ) {
for(int x=0; x<w*3; ) {
raw_rgb[i++] = row_pointers[y][x++]; // red
raw_rgb[i++] = row_pointers[y][x++]; // green
raw_rgb[i++] = row_pointers[y][x++]; // blue
}
}

// Do Something

png_destroy_read_struct( &png_ptr, &info_ptr, 0);

// ---------------------------------

png_structp wpng_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_infop winfo_ptr = png_create_info_struct(wpng_ptr);
setjmp(png_jmpbuf(wpng_ptr));

png_set_IHDR(wpng_ptr, winfo_ptr, 720, 720, 8,
PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
png_set_rows(wpng_ptr, winfo_ptr, &raw_rgb);

ImageTarget itarget;
itarget.data = nullptr;
itarget.size = 0;
png_set_write_fn(wpng_ptr, &itarget, pngWriteCallback, NULL);

png_write_png(wpng_ptr, winfo_ptr, PNG_TRANSFORM_IDENTITY, NULL);

cout << "Output file name: " << Output_PNG << endl;
write_png(Output_PNG, itarget.data, length);
return 0;
}


The makefile I use: here.



After compile and run my code, I see the output (I have verified the c.png I used is a PNG file by Irfanview):



Image width (from PNG file): 720
Image height (from PNG file): 720
- length ----------- 8
- nsize ----------- 8
- data ------ 0
- length ----------- 8
- nsize ----------- 16
- data ------ 22161152
- length ----------- 13
- nsize ----------- 29
- data ------ 22161152
- length ----------- 4
- nsize ----------- 33
- data ------ 22161152
[1] 6675 segmentation fault (core dumped) ./png_from_buffer


Check the core file with gdb, here is the output:



#0  __memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:35
#1 0x00007f3c41b3caf0 in png_write_row () from /lib/x86_64-linux-gnu/libpng12.so.0
#2 0x00007f3c41b3cd78 in png_write_image () from /lib/x86_64-linux-gnu/libpng12.so.0
#3 0x00007f3c41b3d61b in png_write_png () from /lib/x86_64-linux-gnu/libpng12.so.0
#4 0x000000000040269c in main () at main.cpp:181


I tried using different buffer, convert to vector<unsigned char*> as the rows. No luck so far. Any idea will be appreciated.



My environment, if matters:




  • Ubuntu 16.04

  • libpng 1.2


    • libpng12-0/xenial-updates,xenial-security,now 1.2.54-1ubuntu1.1 amd64 [installed]

    • libpng12-dev/xenial-updates,xenial-security,now 1.2.54-1ubuntu1.1 amd64 [installed,automatic]



  • g++ (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609










share|improve this question















My project need to receive a PNG file content over HTTP request, do something to the image and sending back the generated PNG back in the HTTP response. All code need to be done in C/C++.



I'm new to libpng. So I try to write a prototype, reading a PNG file into unsigned char buffer, get the RGB values out (ignore alpha), do no-op, create a new unsigned char buffer with PNG file content, write the new file to the disk and validate I "generate" the same image. I have referenced this question in StackOverflow



My code (with some unrelated function removed, full runnable code is here):



#include <iostream>
#include <fstream>
#include <string>
#include <vector>

#include <png.h>

using namespace std;

typedef struct
{
png_bytep data;
int size;
} ImageTarget;

int read_png(string file_path, unsigned char** buffer)
{
// ... ...
}

void write_png(string file_path, unsigned char* buffer, int length)
{
// ... ...
}

static void pngReadCallback(png_structp png_ptr, png_bytep data, png_size_t length)
{
// ... ...
}

void pngWriteCallback(png_structp png_ptr, png_bytep data, png_size_t length)
{
cout << "- length ----------- " << length << endl;
ImageTarget * itarget = (ImageTarget*)png_get_io_ptr(png_ptr);
size_t nsize = itarget->size + length;
cout << "- nsize ----------- " << nsize << endl;
cout << "- data ------ " << (size_t) itarget->data << endl;

if(itarget->data != nullptr)
itarget->data = (unsigned char*)realloc(itarget->data, nsize);
else
itarget->data = (unsigned char*)malloc(nsize);

memcpy(itarget->data + itarget->size, data, length);
itarget->size += length;
}

int main()
{
const string Input_PNG = "pic/c.png";
const string Output_PNG = "output/output.png";

unsigned char* buffer = nullptr;
int length = read_png(Input_PNG, &buffer);

png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
png_infop info_ptr = png_create_info_struct(png_ptr);

ImageSource imgsource;
imgsource.data = buffer;
imgsource.size = length;
imgsource.offset = 0;
png_set_read_fn(png_ptr, &imgsource, pngReadCallback);

png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_ALPHA, 0);
int w = png_get_image_width( png_ptr, info_ptr );
int h = png_get_image_height( png_ptr, info_ptr );

cout << "Image width (from PNG file): " << w << endl;
cout << "Image height (from PNG file): " << h << endl;

png_bytep* row_pointers = png_get_rows( png_ptr, info_ptr );
png_bytep raw_rgb = (png_bytep)malloc(w * h * 3);
int i = 0;
for(int y=0; y<h; ++y ) {
for(int x=0; x<w*3; ) {
raw_rgb[i++] = row_pointers[y][x++]; // red
raw_rgb[i++] = row_pointers[y][x++]; // green
raw_rgb[i++] = row_pointers[y][x++]; // blue
}
}

// Do Something

png_destroy_read_struct( &png_ptr, &info_ptr, 0);

// ---------------------------------

png_structp wpng_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_infop winfo_ptr = png_create_info_struct(wpng_ptr);
setjmp(png_jmpbuf(wpng_ptr));

png_set_IHDR(wpng_ptr, winfo_ptr, 720, 720, 8,
PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
png_set_rows(wpng_ptr, winfo_ptr, &raw_rgb);

ImageTarget itarget;
itarget.data = nullptr;
itarget.size = 0;
png_set_write_fn(wpng_ptr, &itarget, pngWriteCallback, NULL);

png_write_png(wpng_ptr, winfo_ptr, PNG_TRANSFORM_IDENTITY, NULL);

cout << "Output file name: " << Output_PNG << endl;
write_png(Output_PNG, itarget.data, length);
return 0;
}


The makefile I use: here.



After compile and run my code, I see the output (I have verified the c.png I used is a PNG file by Irfanview):



Image width (from PNG file): 720
Image height (from PNG file): 720
- length ----------- 8
- nsize ----------- 8
- data ------ 0
- length ----------- 8
- nsize ----------- 16
- data ------ 22161152
- length ----------- 13
- nsize ----------- 29
- data ------ 22161152
- length ----------- 4
- nsize ----------- 33
- data ------ 22161152
[1] 6675 segmentation fault (core dumped) ./png_from_buffer


Check the core file with gdb, here is the output:



#0  __memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:35
#1 0x00007f3c41b3caf0 in png_write_row () from /lib/x86_64-linux-gnu/libpng12.so.0
#2 0x00007f3c41b3cd78 in png_write_image () from /lib/x86_64-linux-gnu/libpng12.so.0
#3 0x00007f3c41b3d61b in png_write_png () from /lib/x86_64-linux-gnu/libpng12.so.0
#4 0x000000000040269c in main () at main.cpp:181


I tried using different buffer, convert to vector<unsigned char*> as the rows. No luck so far. Any idea will be appreciated.



My environment, if matters:




  • Ubuntu 16.04

  • libpng 1.2


    • libpng12-0/xenial-updates,xenial-security,now 1.2.54-1ubuntu1.1 amd64 [installed]

    • libpng12-dev/xenial-updates,xenial-security,now 1.2.54-1ubuntu1.1 amd64 [installed,automatic]



  • g++ (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609







c++ libpng






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 10 at 8:16

























asked Nov 10 at 7:54









NonStatic

3061213




3061213








  • 3




    Minimal, Complete, and Verifiable example or it didn't happen.
    – Swordfish
    Nov 10 at 8:02










  • Thank you @Swordfish! I do have a compilable cpp file and makefile in the link. They are too long and I do not want to make this post contain the full content. Could you please try click on the link and help me taking a look? Thanks!
    – NonStatic
    Nov 10 at 8:04










  • @NonStatic Example needs to be Minimal to fit into the post. Actually the posted snippet is full of dangerous raw pointer juggling and wild casts. You should probably fix all that stuff because it is the third most common reason of program bugs.
    – VTT
    Nov 10 at 8:08












  • This is just a prototype to learn/understand libpng APIs. I will definitely not using those raw pointers in my product code.
    – NonStatic
    Nov 10 at 8:10










  • please, go and write up a Minimal, Complete, and Verifiable example that shows the behaviour you have a question about.
    – Swordfish
    Nov 10 at 8:11














  • 3




    Minimal, Complete, and Verifiable example or it didn't happen.
    – Swordfish
    Nov 10 at 8:02










  • Thank you @Swordfish! I do have a compilable cpp file and makefile in the link. They are too long and I do not want to make this post contain the full content. Could you please try click on the link and help me taking a look? Thanks!
    – NonStatic
    Nov 10 at 8:04










  • @NonStatic Example needs to be Minimal to fit into the post. Actually the posted snippet is full of dangerous raw pointer juggling and wild casts. You should probably fix all that stuff because it is the third most common reason of program bugs.
    – VTT
    Nov 10 at 8:08












  • This is just a prototype to learn/understand libpng APIs. I will definitely not using those raw pointers in my product code.
    – NonStatic
    Nov 10 at 8:10










  • please, go and write up a Minimal, Complete, and Verifiable example that shows the behaviour you have a question about.
    – Swordfish
    Nov 10 at 8:11








3




3




Minimal, Complete, and Verifiable example or it didn't happen.
– Swordfish
Nov 10 at 8:02




Minimal, Complete, and Verifiable example or it didn't happen.
– Swordfish
Nov 10 at 8:02












Thank you @Swordfish! I do have a compilable cpp file and makefile in the link. They are too long and I do not want to make this post contain the full content. Could you please try click on the link and help me taking a look? Thanks!
– NonStatic
Nov 10 at 8:04




Thank you @Swordfish! I do have a compilable cpp file and makefile in the link. They are too long and I do not want to make this post contain the full content. Could you please try click on the link and help me taking a look? Thanks!
– NonStatic
Nov 10 at 8:04












@NonStatic Example needs to be Minimal to fit into the post. Actually the posted snippet is full of dangerous raw pointer juggling and wild casts. You should probably fix all that stuff because it is the third most common reason of program bugs.
– VTT
Nov 10 at 8:08






@NonStatic Example needs to be Minimal to fit into the post. Actually the posted snippet is full of dangerous raw pointer juggling and wild casts. You should probably fix all that stuff because it is the third most common reason of program bugs.
– VTT
Nov 10 at 8:08














This is just a prototype to learn/understand libpng APIs. I will definitely not using those raw pointers in my product code.
– NonStatic
Nov 10 at 8:10




This is just a prototype to learn/understand libpng APIs. I will definitely not using those raw pointers in my product code.
– NonStatic
Nov 10 at 8:10












please, go and write up a Minimal, Complete, and Verifiable example that shows the behaviour you have a question about.
– Swordfish
Nov 10 at 8:11




please, go and write up a Minimal, Complete, and Verifiable example that shows the behaviour you have a question about.
– Swordfish
Nov 10 at 8:11












1 Answer
1






active

oldest

votes

















up vote
0
down vote



accepted










I figured out a solution: using libpng v1.6 and the problem could be fixed easily as below:



// READING....

png_image image;
memset(&image, 0, (sizeof image));
image.version = PNG_IMAGE_VERSION;
if (png_image_begin_read_from_memory(&image, file_buffer, length) == 0)
{
return -1;
}

png_bytep buffer;
image.format = PNG_FORMAT_BGR;
size_t input_data_length = PNG_IMAGE_SIZE(image);
buffer = (png_bytep)malloc(input_data_length);
memset(buffer, 0, input_data_length);

if (png_image_finish_read(&image, NULL, buffer, 0, NULL) == 0)
{
return -1;
}


Writing to a memory buffer is also quite easy:



// WRITING......

png_image wimage;
memset(&wimage, 0, (sizeof wimage));
wimage.version = PNG_IMAGE_VERSION;
wimage.format = PNG_FORMAT_BGR;
wimage.height = 720;
wimage.width = 720;

// Get memory size
bool wresult = png_image_write_to_memory(&wimage, nullptr, &wlength, 0, buffer, 0, nullptr);
if (!wresult)
{
cout << "Error: " << image.message << endl;
}

// Real write to memory
unsigned char* wbuffer = (unsigned char*)malloc(wlength);
wresult = png_image_write_to_memory(&wimage, wbuffer, &wlength, 0, buffer, 0, nullptr);

write_png(Output_PNG, wbuffer, wlength);





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237065%2fusing-libpng-1-2-to-write-rgb-image-buffer-to-png-buffer-in-memory-causing-segme%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote



    accepted










    I figured out a solution: using libpng v1.6 and the problem could be fixed easily as below:



    // READING....

    png_image image;
    memset(&image, 0, (sizeof image));
    image.version = PNG_IMAGE_VERSION;
    if (png_image_begin_read_from_memory(&image, file_buffer, length) == 0)
    {
    return -1;
    }

    png_bytep buffer;
    image.format = PNG_FORMAT_BGR;
    size_t input_data_length = PNG_IMAGE_SIZE(image);
    buffer = (png_bytep)malloc(input_data_length);
    memset(buffer, 0, input_data_length);

    if (png_image_finish_read(&image, NULL, buffer, 0, NULL) == 0)
    {
    return -1;
    }


    Writing to a memory buffer is also quite easy:



    // WRITING......

    png_image wimage;
    memset(&wimage, 0, (sizeof wimage));
    wimage.version = PNG_IMAGE_VERSION;
    wimage.format = PNG_FORMAT_BGR;
    wimage.height = 720;
    wimage.width = 720;

    // Get memory size
    bool wresult = png_image_write_to_memory(&wimage, nullptr, &wlength, 0, buffer, 0, nullptr);
    if (!wresult)
    {
    cout << "Error: " << image.message << endl;
    }

    // Real write to memory
    unsigned char* wbuffer = (unsigned char*)malloc(wlength);
    wresult = png_image_write_to_memory(&wimage, wbuffer, &wlength, 0, buffer, 0, nullptr);

    write_png(Output_PNG, wbuffer, wlength);





    share|improve this answer



























      up vote
      0
      down vote



      accepted










      I figured out a solution: using libpng v1.6 and the problem could be fixed easily as below:



      // READING....

      png_image image;
      memset(&image, 0, (sizeof image));
      image.version = PNG_IMAGE_VERSION;
      if (png_image_begin_read_from_memory(&image, file_buffer, length) == 0)
      {
      return -1;
      }

      png_bytep buffer;
      image.format = PNG_FORMAT_BGR;
      size_t input_data_length = PNG_IMAGE_SIZE(image);
      buffer = (png_bytep)malloc(input_data_length);
      memset(buffer, 0, input_data_length);

      if (png_image_finish_read(&image, NULL, buffer, 0, NULL) == 0)
      {
      return -1;
      }


      Writing to a memory buffer is also quite easy:



      // WRITING......

      png_image wimage;
      memset(&wimage, 0, (sizeof wimage));
      wimage.version = PNG_IMAGE_VERSION;
      wimage.format = PNG_FORMAT_BGR;
      wimage.height = 720;
      wimage.width = 720;

      // Get memory size
      bool wresult = png_image_write_to_memory(&wimage, nullptr, &wlength, 0, buffer, 0, nullptr);
      if (!wresult)
      {
      cout << "Error: " << image.message << endl;
      }

      // Real write to memory
      unsigned char* wbuffer = (unsigned char*)malloc(wlength);
      wresult = png_image_write_to_memory(&wimage, wbuffer, &wlength, 0, buffer, 0, nullptr);

      write_png(Output_PNG, wbuffer, wlength);





      share|improve this answer

























        up vote
        0
        down vote



        accepted







        up vote
        0
        down vote



        accepted






        I figured out a solution: using libpng v1.6 and the problem could be fixed easily as below:



        // READING....

        png_image image;
        memset(&image, 0, (sizeof image));
        image.version = PNG_IMAGE_VERSION;
        if (png_image_begin_read_from_memory(&image, file_buffer, length) == 0)
        {
        return -1;
        }

        png_bytep buffer;
        image.format = PNG_FORMAT_BGR;
        size_t input_data_length = PNG_IMAGE_SIZE(image);
        buffer = (png_bytep)malloc(input_data_length);
        memset(buffer, 0, input_data_length);

        if (png_image_finish_read(&image, NULL, buffer, 0, NULL) == 0)
        {
        return -1;
        }


        Writing to a memory buffer is also quite easy:



        // WRITING......

        png_image wimage;
        memset(&wimage, 0, (sizeof wimage));
        wimage.version = PNG_IMAGE_VERSION;
        wimage.format = PNG_FORMAT_BGR;
        wimage.height = 720;
        wimage.width = 720;

        // Get memory size
        bool wresult = png_image_write_to_memory(&wimage, nullptr, &wlength, 0, buffer, 0, nullptr);
        if (!wresult)
        {
        cout << "Error: " << image.message << endl;
        }

        // Real write to memory
        unsigned char* wbuffer = (unsigned char*)malloc(wlength);
        wresult = png_image_write_to_memory(&wimage, wbuffer, &wlength, 0, buffer, 0, nullptr);

        write_png(Output_PNG, wbuffer, wlength);





        share|improve this answer














        I figured out a solution: using libpng v1.6 and the problem could be fixed easily as below:



        // READING....

        png_image image;
        memset(&image, 0, (sizeof image));
        image.version = PNG_IMAGE_VERSION;
        if (png_image_begin_read_from_memory(&image, file_buffer, length) == 0)
        {
        return -1;
        }

        png_bytep buffer;
        image.format = PNG_FORMAT_BGR;
        size_t input_data_length = PNG_IMAGE_SIZE(image);
        buffer = (png_bytep)malloc(input_data_length);
        memset(buffer, 0, input_data_length);

        if (png_image_finish_read(&image, NULL, buffer, 0, NULL) == 0)
        {
        return -1;
        }


        Writing to a memory buffer is also quite easy:



        // WRITING......

        png_image wimage;
        memset(&wimage, 0, (sizeof wimage));
        wimage.version = PNG_IMAGE_VERSION;
        wimage.format = PNG_FORMAT_BGR;
        wimage.height = 720;
        wimage.width = 720;

        // Get memory size
        bool wresult = png_image_write_to_memory(&wimage, nullptr, &wlength, 0, buffer, 0, nullptr);
        if (!wresult)
        {
        cout << "Error: " << image.message << endl;
        }

        // Real write to memory
        unsigned char* wbuffer = (unsigned char*)malloc(wlength);
        wresult = png_image_write_to_memory(&wimage, wbuffer, &wlength, 0, buffer, 0, nullptr);

        write_png(Output_PNG, wbuffer, wlength);






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 12 at 8:28

























        answered Nov 11 at 9:11









        NonStatic

        3061213




        3061213






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237065%2fusing-libpng-1-2-to-write-rgb-image-buffer-to-png-buffer-in-memory-causing-segme%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Florida Star v. B. J. F.

            Danny Elfman

            Lugert, Oklahoma