Logo Search packages:      
Sourcecode: earth3d version File versions  Download package

pngutils.cpp

#include "pngutils.h"
#include <assert.h>

namespace PNGUtils {
  void readPNG(char *source, int sourcesize, char *destination, int destinationsize) {
    //     memcpy(destination, source, sourcesize);
    //     return;
#ifdef EARTH3DDEBUG
    printf("start readPNG sourcesize=%i destinationsize=%i\n", sourcesize, destinationsize);
#endif
    png_structp png_ptr;
    png_infop info_ptr;
    png_uint_32 width, height;

    if (destinationsize<=8) return;
    if (png_sig_cmp((png_bytep) source, (png_size_t)0, 4)) return;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    assert(png_ptr!=NULL);
    info_ptr = png_create_info_struct(png_ptr);
    assert(info_ptr!=NULL);
    assert(!setjmp(png_jmpbuf(png_ptr)));

    /* init IO */
    IOBuffer *inbuffer = new IOBuffer(source, sourcesize);
    png_set_read_fn(png_ptr, (png_voidp) inbuffer, user_read_data);

    /* read image */
    int depth, color_type, interlace_type;

    png_read_png(png_ptr, info_ptr, 0, png_voidp_NULL);
//     png_read_end(png_ptr, info_ptr);
    height = png_get_image_height(png_ptr, info_ptr);
    width  = png_get_image_width(png_ptr, info_ptr);
    depth = png_get_bit_depth(png_ptr, info_ptr);
    png_bytep *row_pointers;
    row_pointers = png_get_rows(png_ptr, info_ptr);

#ifdef EARTH3DDEBUG
    printf("PNG depth=%i\n", depth);
#endif
//    png_read_info(png_ptr, info_ptr);
//    png_get_IHDR(png_ptr, info_ptr, &width, &height, &depth, &color_type,
//          &interlace_type, int_p_NULL, int_p_NULL);
   
//    png_bytep row_pointers[height];
   
//    for (int row = 0; row < height; row++) {
//      row_pointers[row] = (png_bytep) png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
//    }
   
//    /* Now it's time to read the image.  One of these methods is REQUIRED */
//    png_read_image(png_ptr, row_pointers);
//    png_read_end(png_ptr, info_ptr);

   /* copy image to our structure */
   for(int row=0; row<height; row++) {
     memcpy(destination+row*width*(depth/8), row_pointers[row], width*(depth/8));
     assert(row*width*(depth/8)+width*(depth/8)<=destinationsize);
   }
   
   /* clean */
   png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
//     png_set_read_fn(png_ptr, NULL, NULL);
   delete(inbuffer);
#ifdef EARTH3DDEBUG
   printf("end readPNG\n");
#endif
  }
  
  void writePNG(char *source, int width, int height, int depth, char *destination, int *destinationsize) {
//     memcpy(destination, source, *destinationsize);
//     return;
#ifdef EARTH3DDEBUG
    printf("start writePNG\n");
#endif
    png_structp png_ptr;
    png_infop info_ptr;
    png_colorp palette;

    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    assert(png_ptr!=NULL);

    /* Allocate/initialize the image information data.  REQUIRED */
    info_ptr = png_create_info_struct(png_ptr);
    assert(info_ptr!=NULL);
    assert(!setjmp(png_jmpbuf(png_ptr)));
    
    png_set_IHDR(png_ptr, info_ptr, width, height, depth, depth==16 ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

    /* init IO */
    IOBuffer outbuffer(destination, *destinationsize);
    png_set_write_fn(png_ptr, &outbuffer, user_write_data, user_flush_data);
    
    png_bytep *row_pointers;
    row_pointers = new png_bytep[height];
    
    /* copy image to our structure */
    for(int row=0; row<height; row++) {
      row_pointers[row]=(png_bytep) source+row*width*(depth/8);
    }

    /* write image */
//     png_write_png(png_ptr, info_ptr, NULL, NULL);
    png_write_info(png_ptr, info_ptr);
    png_write_image(png_ptr, row_pointers);
    png_write_end(png_ptr, info_ptr);
    
    /* clean */
    delete[](row_pointers);
//     png_set_write_fn(png_ptr, NULL, NULL, NULL);
    png_destroy_write_struct(&png_ptr, &info_ptr);
#ifdef EARTH3DDEBUG
    printf("end writePNG size=%i\n", outbuffer.pos);
#endif

    /* set size */
    *destinationsize = outbuffer.pos;
  }

  void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) {
    if (!data) return;

    IOBuffer *inbuffer = (IOBuffer *) png_get_io_ptr(png_ptr);
//     printf("user_read_data data: %li buffer: %li length: %li\n", data, inbuffer, length);
//     data[0]=0;
//     printf("wrote to data\n");
    if (inbuffer->pos+length>inbuffer->size) {
      memset((void *) data, 0, length);
    }
    else {
      memcpy((void *) data, inbuffer->buffer+inbuffer->pos, length);
    }
    inbuffer->pos += length;
    assert(inbuffer->pos <= inbuffer->size+8);
    assert(length>=0);
  }

  void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length) {
    if (!data) return;

    IOBuffer *outbuffer = (IOBuffer *) png_get_io_ptr(png_ptr);
    memcpy(outbuffer->buffer+outbuffer->pos, data, length);
    outbuffer->pos += length;
    assert(outbuffer->pos < outbuffer->size);
    assert(length>=0);
  }

  void user_flush_data(png_structp png_ptr) {
  }
};

Generated by  Doxygen 1.6.0   Back to index