2012-02-20 12 views
5

मैं OpenCL के साथ उपयोग के लिए सी के साथ एक पीएनजी फ़ाइल पढ़ने की कोशिश कर रहा हूं। ओपनसीएल के पास 24-बिट आरजीबी छवियों के लिए कोई समर्थन नहीं है इसलिए मुझे आरजीबी से आरजीबीए तक डेटा का विस्तार करने की आवश्यकता है। मैं जिन पीएनजी का उपयोग कर रहा हूं वे सभी 24-बिट हैं ताकि सिरदर्द से बचा जा सके।libpng png_set_add_alpha | png_set_filler त्रुटि: अनुक्रमिक पंक्ति ओवरफ़्लो

मैं png_set_filler और png_set_add_alpha जो मुझे लगता है का उपयोग करने का प्रयास किया मोटे तौर पर समस्या को हल करने के समान हैं, लेकिन वे दोनों इस त्रुटि का कारण: पूर्ण में

libpng error: sequential row overflow 

यहाँ समारोह है:

int LoadPNG24(unsigned char ** pixelBuffer, const char *filename, unsigned int *width, unsigned int *height) { 
    png_byte header[8]; 

    //open file as binary 
    FILE *fp = fopen(filename, "rb"); 
    if (!fp) { 
     return TEXTURE_LOAD_ERROR; 
    } 

    //read the header 
    fread(header, 1, 8, fp); 

    //test if png 
    int is_png = !png_sig_cmp(header, 0, 8); 
    if (!is_png) { 
     fclose(fp); 
     return TEXTURE_LOAD_ERROR; 
    } 

    //create png struct 
    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 
    if (!png_ptr) { 
     fclose(fp); 
     return (TEXTURE_LOAD_ERROR); 
    } 

    //create png info struct 
    png_infop info_ptr = png_create_info_struct(png_ptr); 
    if (!info_ptr) { 
     png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); 
     fclose(fp); 
     return (TEXTURE_LOAD_ERROR); 
    } 

    //create png info struct 
    png_infop end_info = png_create_info_struct(png_ptr); 
    if (!end_info) { 
     png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); 
     fclose(fp); 
     return (TEXTURE_LOAD_ERROR); 
    } 

    //png error stuff, not sure libpng man suggests this. 
    if (setjmp(png_jmpbuf(png_ptr))) { 
     png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 
     fclose(fp); 
     return (TEXTURE_LOAD_ERROR); 
    } 

    //init png reading 
    png_init_io(png_ptr, fp); 

    //let libpng know you already read the first 8 bytes 
    png_set_sig_bytes(png_ptr, 8); 

    // read all the info up to the image data 
    png_read_info(png_ptr, info_ptr); 

    //variables to pass to get info 
    int bit_depth, color_type; 
    png_uint_32 twidth, theight; 

    // get info about png 
    png_get_IHDR(png_ptr, info_ptr, &twidth, &theight, &bit_depth, &color_type, NULL, NULL, NULL); 

    // Update the png info struct. 
    png_read_update_info(png_ptr, info_ptr); 

    // Row size in bytes. 
    //png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr); 
    png_size_t rowbytes = sizeof(png_byte) * 4 * twidth; 

    // Allocate the image_data as a big block, to be given to opencl 
    png_byte *image_data = (png_byte *)malloc(sizeof(png_byte) * 4 * twidth * theight); 
    if (!image_data) { 
     //clean up memory and close stuff 
     png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 
     fclose(fp); 
     return TEXTURE_LOAD_ERROR; 
    } 

    //row_pointers is for pointing to image_data for reading the png with libpng 
    png_bytep *row_pointers = (png_bytep *)malloc(sizeof(png_bytep) * theight); 
    if (!row_pointers) { 
     //clean up memory and close stuff 
     png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 
     free(image_data); 
     fclose(fp); 
     return TEXTURE_LOAD_ERROR; 
    } 

    // set the individual row_pointers to point at the correct offsets of image_data 
    for (int i = 0; i < theight; ++i) { 
     row_pointers[i] = image_data + (i * rowbytes); 
    } 

    // PNG Transforms 
    if (color_type == PNG_COLOR_TYPE_RGB) { 
     //png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); 
     png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER); 
    } 

    //read the png into image_data through row_pointers 
    png_read_image(png_ptr, row_pointers); 

    //clean up memory and close stuff 
    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 
    free(row_pointers); 
    fclose(fp); 

    //update width and height based on png info 
    (*pixelBuffer) = image_data; 
    if (width) {*width = twidth;} 
    if (height) {*height = theight;} 

    return TEXTURE_LOAD_OK; 
} 

धन्यवाद।

उत्तर

7

ठीक है, थोड़ी अधिक गुगलिंग ने उत्तर प्रदान किया।

png_read_update_info(png_ptr, info_ptr); 

तब्दील अद्यतन जानकारी ptr और पंक्ति संकेत के बाद जोड़ा जा रहा है और समस्या ठीक हो गई।

मैं इस समस्या के साथ किसी और की मदद करने की उम्मीद में उत्तर छोड़ दूंगा।