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
c++ libpng
|
show 1 more comment
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
c++ libpng
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
|
show 1 more comment
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
c++ libpng
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
c++ libpng
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
|
show 1 more comment
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
|
show 1 more comment
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);
add a comment |
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);
add a comment |
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);
add a comment |
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);
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);
edited Nov 12 at 8:28
answered Nov 11 at 9:11
NonStatic
3061213
3061213
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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