libpng png_set_read_fn troubles

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Wil
Posts: 15
Joined: Wed Feb 23, 2005 7:30 pm
Location: Las Vegas
Contact:

libpng png_set_read_fn troubles

Post by Wil »

I am attempting to modify libpng and Lua's graphics.cpp file to allow the useage of extracting an image from a rar file directly into libpng without ever writing anything to the memory stick.

Code: Select all

Image* loadPngImage(const char* filename, const char* rarfile)
{
        png_structp png_ptr;
        png_infop info_ptr;
        unsigned int sig_read = 0;
        png_uint_32 width, height, x, y;
        int bit_depth, color_type, interlace_type;
        u32* line;
        FILE *fp;
	hardrarfile = (char*)rarfile;
        Image* image = (Image*) malloc(sizeof(Image));
        if (!image) return NULL;

        if ((fp = fopen(filename, "rb")) == NULL) return NULL;
        png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
        if (png_ptr == NULL) {
                free(image);
                fclose(fp);
                return NULL;;
        }
			png_set_read_fn(png_ptr, NULL, user_read_data_fn);
        png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) NULL, user_warning_fn);
        info_ptr = png_create_info_struct(png_ptr);
        if (info_ptr == NULL) {
                free(image);
                fclose(fp);
                png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
                return NULL;
        }
        png_init_io(png_ptr, fp);
        png_set_sig_bytes(png_ptr, sig_read);
        png_read_info(png_ptr, info_ptr);
        png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL);
        if (width > 512 || height > 512) {
                free(image);
                fclose(fp);
                png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
                return NULL;
        }
        image->imageWidth = width;
        image->imageHeight = height;
        image->textureWidth = getNextPower2(width);
        image->textureHeight = getNextPower2(height);
        png_set_strip_16(png_ptr);
        png_set_packing(png_ptr);
        if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr);
        if &#40;color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8&#41; png_set_gray_1_2_4_to_8&#40;png_ptr&#41;;
        if &#40;png_get_valid&#40;png_ptr, info_ptr, PNG_INFO_tRNS&#41;&#41; png_set_tRNS_to_alpha&#40;png_ptr&#41;;
        png_set_filler&#40;png_ptr, 0xff, PNG_FILLER_AFTER&#41;;
        image->data = &#40;Color*&#41; memalign&#40;16, image->textureWidth * image->textureHeight * sizeof&#40;Color&#41;&#41;;
        if &#40;!image->data&#41; &#123;
                free&#40;image&#41;;
                fclose&#40;fp&#41;;
                png_destroy_read_struct&#40;&png_ptr, png_infopp_NULL, png_infopp_NULL&#41;;
                return NULL;
        &#125;
        line = &#40;u32*&#41; malloc&#40;width * 4&#41;;
        if &#40;!line&#41; &#123;
                free&#40;image->data&#41;;
                free&#40;image&#41;;
                fclose&#40;fp&#41;;
                png_destroy_read_struct&#40;&png_ptr, png_infopp_NULL, png_infopp_NULL&#41;;
                return NULL;
        &#125;
        for &#40;y = 0; y < height; y++&#41; &#123;
                png_read_row&#40;png_ptr, &#40;u8*&#41; line, png_bytep_NULL&#41;;
                for &#40;x = 0; x < width; x++&#41; &#123;
                        u32 color = line&#91;x&#93;;
                        image->data&#91;x + y * image->textureWidth&#93; =  color;
                &#125;
        &#125;
        free&#40;line&#41;;
        png_read_end&#40;png_ptr, info_ptr&#41;;
        png_destroy_read_struct&#40;&png_ptr, &info_ptr, png_infopp_NULL&#41;;
        fclose&#40;fp&#41;;
        return image;
&#125;
The actual function to do so is indented further.

So, as follows, this is my custom function to read the data from the rar file and right back into libpng.

Code: Select all

char *hardrarfile;
png_structp last_ptr;
char *data_ptr;

void user_read_data_fn&#40;png_structp png_ptr, png_bytep data, png_size_t length&#41; &#123;

	unsigned long data_size;

	if &#40;last_ptr != png_ptr->io_ptr&#41; &#123;
		
		free&#40;data_ptr&#41;;
		urarlib_get&#40;&data_ptr, &data_size, hardrarfile, &#40;png_FILE_p&#41;png_ptr->io_ptr, "MaySeptember8891"&#41;;
		last_ptr = &#40;png_struct*&#41;png_ptr->io_ptr;
		pspDebugScreenPrintf&#40;"^ READ RAR SUCESS\n"&#41;;

	&#125; else &#123; pspDebugScreenPrintf&#40;"^ SKIPPING READ RAR DUE TO PREVIOUS ACCESS\n"&#41;; &#125;


	strncpy&#40;&#40;char*&#41;data, &#40;const char*&#41;data_ptr, &#40;int&#41;length&#41;;

	pspDebugScreenPrintf&#40;"^ STRCOPY TO PNG DATA SUCESS\n"&#41;;
	
&#125;
Basically urarlib_get grabs the file (hardrarfile) and places it into data_ptr. Works fine, extracts it like it is supposed to.

It prints out as such:

^ READ RAR SUCESS
^ STRCOPY TO PNG DATA SUCESS
^ SKIPPING READ RAR DUE TO PREVIOUS ACCESS
^ STRCOPY TO PNG DATA SUCESS

However, in my main.cpp file it does not continue after I attempt to load the PNG. It doesn't freeze, it just stops, and doesn't display the image.

Code: Select all

	pspDebugScreenInit&#40;&#41;;
	SetupCallbacks&#40;&#41;;

	initGraphics&#40;&#41;;

	Image* testimage;

	printf&#40;"^ CALLING LOADPNG\n"&#41;;

	testimage = loadPngImage&#40;"data.rar", "rro.png"&#41;;

	printf&#40;"^ LOADPNG SUCESS\n^ CALLING BLIT TO SCREEN\n"&#41;;

	blitAlphaImageToScreen&#40;0, 0, 480, 272, testimage, 0, 0&#41;;

	flipScreen&#40;&#41;;
Again, it never displays ^ LOADPNG SUCESS or anything past that.


Hopefully this is enough information so in turn you can help me out. Anyone have any ideas? Thanks.
Wil
Wil
Posts: 15
Joined: Wed Feb 23, 2005 7:30 pm
Location: Las Vegas
Contact:

Post by Wil »

Heh, got it working!

Incase someone was wondering HOW -- I realized that since fread wasn't being rewound that it's likely I need to add an offset option so that it will read from it's last position. It worked further but still had a problem so what I ended up doing was using png_memcpy instead of strncopy.

Thanks for all who... looked ;)
Wil
patpsp
Posts: 31
Joined: Tue Oct 25, 2005 5:24 pm

Post by patpsp »

Please post your corrected code, so that it could be a sample for people searching this functionality.

thanks
User avatar
daurnimator
Posts: 38
Joined: Sun Dec 11, 2005 8:36 pm
Location: melbourne, australia

Post by daurnimator »

I'm SO DAMN SICK OF THIS FORUM AND THE SEARCH TOOL

its all you care about - stuff the searches, let people ask their own questions.

I've seen SO many good threads destroyed by being told to use the search function - where they had a unique case.

I'm sure many people have permanently left psp programming by this attitude.
patpsp
Posts: 31
Joined: Tue Oct 25, 2005 5:24 pm

Post by patpsp »

If you say this because of my post, please read again what I wrote :

I asked him to give his corrected code, so that it could be a sample.
I never asked him to use search function.

Please read !!!!!
User avatar
daurnimator
Posts: 38
Joined: Sun Dec 11, 2005 8:36 pm
Location: melbourne, australia

Post by daurnimator »

i know, but this is the attitude still, by getting him to post his code, you are fostering the use of the search tool.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

Yet the search function exists and is a great help for someone searching for a solution to some obviously already answered questions. The whole forum is meaningless if noone ever writes down his findings and good codes, so others can learn from it by either searching for it directly, or being forwarded to the answer in their own thread.

Actually I haven't found that huge of an "RTFM"/"UTFS" attitude in this forums yet, so I don't see the problem.

So stop the arguing.
Post Reply