2012-02-20 18 views
5

Próbuję odczytać plik PNG za pomocą C do użycia z OpenCL. OpenCL nie obsługuje 24-bitowych obrazów RGB, więc muszę rozszerzyć dane z RGB do RGBA. Używane przez mnie PNG są 24-bitowe, dzięki czemu można uniknąć bólu głowy.libpng png_set_add_alpha | Błąd png_set_filler: sekwencyjne przepełnienie wiersza

próbowałem użyć png_set_filler i png_set_add_alpha które zakładam, że są mniej więcej takie same, aby rozwiązać problem, ale oboje powodować ten błąd:

libpng error: sequential row overflow 

Oto funkcja w całości:

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; 
} 

Dzięki.

Odpowiedz

7

OK, nieco więcej google pod warunkiem, że odpowiedź.

Dodawanie

png_read_update_info(png_ptr, info_ptr); 

po przekształconej zaktualizowanej PTR informacji i wskaźników wierszy i problem został rozwiązany.

Zostawię odpowiedź tutaj w nadziei, że pomogę komuś w tym problemie.

Powiązane problemy