libpng: Worst manual ever or am I just dense?
The document in question. I've been looking over this thing for 20 minutes now and I still have no idea what I'm looking at or where to start. I have no idea what the functions are, what they do, why they're there, what their arguments are, or what caveats to look out for. Where the heck is the actual documentation for this thing? I'm having an easier time figuring this out by skimming through the source code. Surely that's a sign that something is horribly wrong with their manual. I guess that was more of a rant than an actual question. I'm just lost here. Anyone want to recommend an alternative thread safe cross platform image library that can use custom i/o routines?
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
I remember digging through that document, it is pretty bad. I can post code that uses custom IO routines if you want. Once you have it working with the default file IO, it is not complex to switch it over to the custom routines. You just need these 3 functions:
Then call this for writing images:
Or this for reading:
Each goes after png_create_write_struct or png_create_read_struct. You can access whatever you passed for IO to those png_set_*_fn functions in your callbacks with png_ptr->io_ptr.
I can post my code if that would help.
edit: I'm not sure if you are still intested in libpng, I just got the impression that the problem was IO routines. Reading it again, it doesn't seem that way ;) DevIL is one image library I know of.
void PngRead(png_structp png_ptr, png_bytep data, png_size_t length);void PngWrite(png_structp png_ptr, png_bytep data, png_size_t length);void PngFlush(png_structp png_ptr);
Then call this for writing images:
png_set_write_fn(PngStruct, &IO, PngWrite, PngFlush);
Or this for reading:
png_set_read_fn(PngStruct, &IO, PngRead);
Each goes after png_create_write_struct or png_create_read_struct. You can access whatever you passed for IO to those png_set_*_fn functions in your callbacks with png_ptr->io_ptr.
I can post my code if that would help.
edit: I'm not sure if you are still intested in libpng, I just got the impression that the problem was IO routines. Reading it again, it doesn't seem that way ;) DevIL is one image library I know of.
I would appreciate that, thank you.
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
Here is a class that implements png handling in my game:
vPng.h
vPng.cpp
I realize it is sorely lacking comments, if there is something you want more explanation with this code I have AIM: dillons23 and ICQ: 205897132.
vPng.h
vPng.cpp
I realize it is sorely lacking comments, if there is something you want more explanation with this code I have AIM: dillons23 and ICQ: 205897132.
I looked at DevIL and FreeImage.
DevIL seems to be a state machine, and the I/O routines seem to be shared globally; I'm pretty sure I don't want that in a multithreaded environment. I could make sure none of my code tries to use it at the same time, but I could still get into trouble if another library or the user decides they want to use it, so I don't think so.
The best FreeImage could do was load an image from memory. I could load my data into memory first before passing it on, but that seems wasteful and inefficient.
There was a few others but they had obscure features for 3D volumes or dozens of strange transformations or drawing and a bunch of other things I don't need or want. That was about where I decided I should just dump the middle man and use libpng directly.
Thanks for the assistance.
DevIL seems to be a state machine, and the I/O routines seem to be shared globally; I'm pretty sure I don't want that in a multithreaded environment. I could make sure none of my code tries to use it at the same time, but I could still get into trouble if another library or the user decides they want to use it, so I don't think so.
The best FreeImage could do was load an image from memory. I could load my data into memory first before passing it on, but that seems wasteful and inefficient.
There was a few others but they had obscure features for 3D volumes or dozens of strange transformations or drawing and a bunch of other things I don't need or want. That was about where I decided I should just dump the middle man and use libpng directly.
Thanks for the assistance.
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
Another thing I just thought of that might be of some use is CxImage. I remember downloading this to get an example usage of libpng and libjpeg, maybe it will help also. I bet their code is better than mine ;)
It works! Well, everything except the PNG_COLOR_MASK_xxx types, because I couldn't figure out how to determine which colour to use as the mask.
Lenna seems to be happy to be more than just a black square on the screen, and the library I'm writing is slowly getting to the point where it is almost able to sort of do something.
And that manual was of no help whatsoever.
Thanks again for the help.
Lenna seems to be happy to be more than just a black square on the screen, and the library I'm writing is slowly getting to the point where it is almost able to sort of do something.
And that manual was of no help whatsoever.
Thanks again for the help.
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
Yeah, the libpng manuals are pretty bad, last I checked. That's one of the problems with trying to be able to handle all and every situation in C. It's gernally a better idea to look at the libpng example programs.
Anyway, at one point I managed to write my own little include file that handled all the boring bits. It's missing explicit documentation, but the names should make sense. Enjoy!
pngio.h
Anyway, at one point I managed to write my own little include file that handled all the boring bits. It's missing explicit documentation, but the names should make sense. Enjoy!
pngio.h
#include <stdio.h>#include <png.h> typedef struct { unsigned char red, green, blue, alpha;} mycolour;typedef struct { FILE* fp; png_structp png; png_infop info; png_infop end; mycolour** rows;} pngstuff;int open_png(char *filename, pngstuff* ret) { png_uint_32 width, height; int y, bit_depth, colour_type, interlace_type; ret->fp = fopen(filename, "rb"); if (!ret->fp) { return 1; } ret->png = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!ret->png) { fclose(ret->fp); return 2; } ret->info = png_create_info_struct(ret->png); if (!ret->info) { png_destroy_read_struct(&ret->png, NULL, NULL); fclose(ret->fp); return 3; } ret->end = png_create_info_struct(ret->png); if (!ret->end) { png_destroy_read_struct(&ret->png, &ret->info, NULL); fclose(ret->fp); return 4; } if (setjmp(png_jmpbuf(ret->png))) { png_destroy_read_struct(&ret->png, &ret->info, &ret->end); fclose(ret->fp); return 5; } png_init_io(ret->png, ret->fp); png_read_info(ret->png, ret->info); png_get_IHDR(ret->png, ret->info, &width, &height, &bit_depth, &colour_type, &interlace_type, NULL, NULL); png_set_strip_16(ret->png); png_set_packing(ret->png); if (colour_type == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb(ret->png); } if (colour_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { png_set_gray_1_2_4_to_8(ret->png); } if (png_get_valid(ret->png, ret->info, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(ret->png); } png_set_filler(ret->png, 0xff, PNG_FILLER_AFTER); if (colour_type == PNG_COLOR_TYPE_GRAY || colour_type == PNG_COLOR_TYPE_GRAY_ALPHA) { png_set_gray_to_rgb(ret->png); } ret->rows = (mycolour**) malloc(height * sizeof(mycolour*)); for (y = 0; y < height; ++y) { ret->rows[y] = (mycolour*) malloc(width * sizeof(mycolour)); } png_read_image(ret->png, (png_bytepp) ret->rows); png_read_end(ret->png, ret->info); return 0;}void close_png(pngstuff* p) { png_destroy_read_struct(&p->png, &p->info, &p->end); fclose(p->fp); p->fp = NULL;}int write_png(char* filename, mycolour** rows, int width, int height) { FILE* fp_out; png_structp ppng_out; png_infop pinfo_out; fp_out = fopen(filename, "wb"); if (!fp_out) { return 1; } ppng_out = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!ppng_out) { fclose(fp_out); return 2; } pinfo_out = png_create_info_struct(ppng_out); if (!pinfo_out) { png_destroy_write_struct(&ppng_out, NULL); fclose(fp_out); return 3; } png_init_io(ppng_out, fp_out); png_set_IHDR(ppng_out, pinfo_out, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_set_rows(ppng_out, pinfo_out, (png_bytepp)rows); if (setjmp(png_jmpbuf(ppng_out))) { png_destroy_write_struct(&ppng_out, &pinfo_out); fclose(fp_out); return 4; } png_write_png(ppng_out, pinfo_out, PNG_TRANSFORM_IDENTITY, NULL); png_destroy_write_struct(&ppng_out, &pinfo_out); fclose(fp_out); return 0;}
My stuff.Shameless promotion: FreePop: The GPL god-sim.
Quote:
Original post by smart_idiot
And that manual was of no help whatsoever.
Thanks again for the help.
Glad I could help. Yeah the manual is pretty worthless. The only place I found it useful was looking up the transforms, which are pretty cool and helpful.
edit: Doc, much agreed on the C API thing. I especially hate the setjmp/longjmp system a lot of C libraries tend to use (libpng included).
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement