2012-02-20 18 views
5

Tôi đang cố đọc tệp PNG bằng C để sử dụng với OpenCL. OpenCL không hỗ trợ hình ảnh RGB 24 bit vì vậy tôi cần phải mở rộng dữ liệu từ RGB sang RGBA. Các PNG tôi đang sử dụng đều là 24-bit để tránh đau đầu.libpng png_set_add_alpha | lỗi png_set_filler: tràn hàng tuần tự

Tôi đã cố gắng sử dụng png_set_filler và png_set_add_alpha mà tôi giả định là xấp xỉ giống hệt nhau để giải quyết vấn đề này nhưng cả hai đều gây ra lỗi này:

libpng error: sequential row overflow 

Dưới đây là các chức năng đầy đủ:

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

Cảm ơn.

Trả lời

7

Ok, một chút googling cung cấp câu trả lời.

Thêm

png_read_update_info(png_ptr, info_ptr); 

Sau khi chuyển đổi cập nhật các ptr thông tin và các con trỏ hàng và khắc phục vấn đề.

Tôi sẽ để lại câu trả lời ở đây với hy vọng giúp đỡ người khác với vấn đề này.

Các vấn đề liên quan