使用libpng读取PNG图片像素数据(2)

// Convert stuff to appropriate formats!
    if(color_type==PNG_COLOR_TYPE_PALETTE)
    {
        png_set_packing(png_ptr);
        png_set_palette_to_rgb(png_ptr); //Expand data to 24-bit RGB or 32-bit RGBA if alpha available.
    }
    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
        png_set_gray_1_2_4_to_8(png_ptr);
    if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png_ptr);
    if (bit_depth == 16)
        png_set_strip_16(png_ptr);


    //Expand paletted or RGB images with transparency to full alpha channels so the data will be available as RGBA quartets.
    if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    {
        png_set_tRNS_to_alpha(png_ptr);
    }

//png_read_update_info(png_ptr, info_ptr);
    u8* rgba = new u8[width * height * 4];  //each pixel(RGBA) has 4 bytes
    png_bytep * row_pointers;
    row_pointers = (png_bytep*)png_malloc(sizeof(png_bytep) * height);
    for (int y = 0; y < height; y++)
    {
        row_pointers[y] = (png_bytep)png_malloc(width<<2); //each pixel(RGBA) has 4 bytes
    }
    png_read_image(png_ptr, row_pointers);

//unlike store the pixel data from top-left corner, store them from bottom-left corner for OGLES Texture drawing...
    int pos = (width * height * 4) - (4 * width);
    for(int row = 0; row < height; row++)
    {
      for(int col = 0; col < (4 * width); col += 4)
      {
          rgba[pos++] = row_pointers[row][col];        // red
          rgba[pos++] = row_pointers[row][col + 1];    // green
          rgba[pos++] = row_pointers[row][col + 2];    // blue
          rgba[pos++] = row_pointers[row][col + 3];    // alpha
      }
      pos=(pos - (width * 4)*2); //move the pointer back two rows
    }

ImageInfo* imageInfo = (ImageInfo*)kdMalloc(sizeof(ImageInfo));
    imageInfo->pixelData = rgba;
    imageInfo->imageHeight = height;
    imageInfo->imageWidth = width;

//clean up after the read, and free any memory allocated
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    return imageInfo;
}

//----------------------------------------------------------------------------------------------------------------

ImageInfo*  decodePNGFromFile(char* fileName)
{
    char png_header[8];
    png_structp png_ptr;
    png_infop info_ptr;
    int width, height, rowBytes;
    png_byte color_type;
    png_byte bit_depth;
    png_colorp palette;

/* open file and test for it being a png */
    FILE *file = fopen(fileName, "rb");
    fread(png_header, 1, 8, file);
    if(png_sig_cmp((png_bytep)png_header, 0, 8))
    {
        TFC_DEBUG("Not a PNG file...");
        fclose(file);
    }
    /* initialise structures for reading a png file */
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    info_ptr = png_create_info_struct(png_ptr);
    if (setjmp(png_jmpbuf(png_ptr)))
    {
        png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
        TFC_DEBUG("ReadPngFile: Failed to read the PNG file");
        fclose(file);
    }
    //I/O initialisation methods
    png_init_io(png_ptr, file);
    png_set_sig_bytes(png_ptr, 8);  //Required!!!


    /* **************************************************
    * The high-level read interface in libpng ()
    * **************************************************
    */
      png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0);
      width = info_ptr->width;
      height = info_ptr->height;
      unsigned char* rgba = new unsigned char[width * height * 4];  //each pixel(RGBA) has 4 bytes
      png_bytep* row_pointers = png_get_rows(png_ptr, info_ptr);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/6d0a90641de29fadf4adad1a21381855.html