Ejemplo n.º 1
0
/**
 * Initialize png reader struct.
 */
void setup_png_reader(const char* data, size_t length, png_structp* outpng_ptr, png_infop* out_info_ptr) {
  if (length <= PNG_HEADER_SIZE || !png_check_sig((png_bytep)data, PNG_HEADER_SIZE)) {
    logstream(LOG_ERROR) << "Invalid PNG signature" << std::endl;
    throw(std::string("Invalid PNG file"));
  }

  // Begin setup
  // main png read struct
  png_structp png_ptr = NULL;
  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, png_error_handler, NULL);
  if(png_ptr == NULL) {
    logstream(LOG_ERROR) << "Fail allocating PNG reader struct" << std::endl;
    throw(std::string("Unexpected libpng error"));
  }

  // png info struct
  png_infop info_ptr = NULL;
  info_ptr = png_create_info_struct(png_ptr);
  if(info_ptr == NULL) {
    // libpng must free file info struct memory before we bail
    png_destroy_read_struct(&png_ptr, NULL, NULL);
    logstream(LOG_ERROR) << "Fail allocating PNG info struct" << std::endl;
    throw(std::string("Unexpected libpng error"));
  }

  *outpng_ptr = png_ptr;
  *out_info_ptr = info_ptr;
}
Ejemplo n.º 2
0
bool PngLoader::load( std::string file )
{
    png_structp png_ptr;
    png_infop info_ptr;
  
    std::ifstream ifile( file.c_str(), std::ios::binary );
 
    if( !ifile.is_open() )
        return false;
 
    char assinatura[8];
    ifile.read( &assinatura[0], 8 * sizeof(char) );
  
    if(!png_check_sig( (png_bytep)assinatura, 8) )
    {
        return false;
    }
 
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
 
    if(png_ptr == 0)
    {
        return false;
    }
 
    info_ptr = png_create_info_struct( png_ptr );
 
    if( info_ptr == 0 )
    {
        png_destroy_read_struct( &png_ptr, 0, 0 );
        return false;
    }
 
    png_set_read_fn( png_ptr, (void*)&ifile, readFileCallback );
 
    png_set_sig_bytes( png_ptr, 8 );
 
    png_read_info( png_ptr, info_ptr );
 
    png_get_IHDR( png_ptr, info_ptr, (png_uint_32*)&width, (png_uint_32*)&height,
                  &depth, &color_type, 0, 0, 0 );
 
    cols = png_get_rowbytes(png_ptr, info_ptr);
 
    png_bytepp row_pp = new png_bytep[height];
    data = new char[ cols * height ];
 
    for( int i = 0; i < height; ++i )
    {
        row_pp[height - i - 1] = (png_bytep)&data[ i * cols ];
    }
 
    png_read_image( png_ptr, row_pp );
    png_read_end( png_ptr, info_ptr );
 
    png_destroy_read_struct( &png_ptr, &info_ptr, 0 );
 
    delete[] row_pp;
    return true;
}
Ejemplo n.º 3
0
uint32 readpng_init(FILE *infile)
{
    uint8 sig[8];

    /* first do a quick check that the file really is a PNG image; could
     * have used slightly more general png_sig_cmp() function instead */

    fread(sig, 1, 8, infile);
    if (!png_check_sig(sig, 8))
        return 1;   /* bad signature */

    /* could pass pointers to user-defined error handlers instead of NULLs: */

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr)
        return 4;   /* out of memory */

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        return 4;   /* out of memory */
    }

    png_init_io(png_ptr, infile);
    png_set_sig_bytes(png_ptr, 8);  /* we already read the 8 signature bytes */

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

    /* OK, that's all we need for now; return happy */

    return 0;
}
Ejemplo n.º 4
0
RawImageData get_raw_image_data_from_png(const void* png_data, const int png_data_size)
{
	assert(png_data != NULL && png_data_size > 8);
	assert(png_check_sig((void*)png_data, 8));

	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	assert(png_ptr != NULL);
	png_infop info_ptr = png_create_info_struct(png_ptr);
	assert(info_ptr != NULL);

	ReadDataHandle png_data_handle = (ReadDataHandle) {{png_data, png_data_size}, 0};
	png_set_read_fn(png_ptr, &png_data_handle, read_png_data_callback);

	if (setjmp(png_jmpbuf(png_ptr)))
    {
		CRASH("Error reading PNG file!");
	}

	const PngInfo png_info = read_and_update_info(png_ptr, info_ptr);
	const DataHandle raw_image = read_entire_png_image(png_ptr, info_ptr, png_info.height);

	png_read_end(png_ptr, info_ptr);
	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

	return (RawImageData)
    {
        png_info.width,
        png_info.height,
        raw_image.size,
        get_gl_color_format(png_info.color_type),
        raw_image.data
    };
}
Ejemplo n.º 5
0
//! returns true if the file maybe is able to be loaded by this class
bool CImageLoaderPng::isALoadableFileFormat(engine::io::IReadFile* file)
{
#ifdef _engine_COMPILE_WITH_LIBPNG_

	if (!file)
		return false;

	// Read the first few bytes of the PNG file
	if (file->read(&g_png_load_buffer, 8) != 8)
	{
		//os::Printer::log("Not a PNG file: can't read file\n", file->getFileName(), ELL_ERROR);
		return false;
	}

	// CHeck if it really is a PNG file
	if (!png_check_sig((png_bytep)g_png_load_buffer, 8))
	{
		//os::Printer::log("Not a PNG file: wrong header\n", file->getFileName(),ELL_ERROR);
		return false;
	}

	return true; //if we are here then it must be a png

#else
	return false;
#endif // _engine_COMPILE_WITH_LIBPNG_
}
Ejemplo n.º 6
0
int FilePNG::check_sig(Asset *asset)
{
	FILE *stream = fopen(asset->path, "rb");

	if(stream)
	{

//printf("FilePNG::check_sig 1\n");
		char test[16];
		fread(test, 16, 1, stream);
		fclose(stream);

		if(png_check_sig((unsigned char*)test, 8))
		{
//printf("FilePNG::check_sig 1\n");
			return 1;
		}
		else
		if(test[0] == 'P' && test[1] == 'N' && test[2] == 'G' && 
			test[3] == 'L' && test[4] == 'I' && test[5] == 'S' && test[6] == 'T')
		{
//printf("FilePNG::check_sig 1\n");
			return 1;
		}
	}
	return 0;
}
Ejemplo n.º 7
0
int readpng_init(FILE *infile, long *pWidth, long *pHeight)
{
    uch sig[8];


    /* first do a quick check that the file really is a PNG image; could
     * have used slightly more general png_sig_cmp() function instead */

    fread(sig, 1, 8, infile);
    if (!png_check_sig(sig, 8))
        return 1;   /* bad signature */


    /* could pass pointers to user-defined error handlers instead of NULLs: */

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr)
        return 4;   /* out of memory */

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        return 4;   /* out of memory */
    }


    /* we could create a second info struct here (end_info), but it's only
     * useful if we want to keep pre- and post-IDAT chunk info separated
     * (mainly for PNG-aware image editors and converters) */


    /* setjmp() must be called in every function that calls a PNG-reading
     * libpng function */

    if (setjmp(png_ptr->jmpbuf)) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return 2;
    }


    png_init_io(png_ptr, infile);
    png_set_sig_bytes(png_ptr, 8);  /* we already read the 8 signature bytes */

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


    /* alternatively, could make separate calls to png_get_image_width(),
     * etc., but want bit_depth and color_type for later [don't care about
     * compression_type and filter_type => NULLs] */

    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
      NULL, NULL, NULL);
    *pWidth = width;
    *pHeight = height;


    /* OK, that's all we need for now; return happy */

    return 0;
}
Ejemplo n.º 8
0
   virtual bool GetImageInfo(dword header, int limit_size_x, int limit_size_y, C_fixed limit_ratio){

      if(!png_check_sig((byte*)&header, 4))
         return false;
      png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, this, PNG_Error, PNG_Error);
      if(!png_ptr)
         return false;
      //E_LOADER_RESULT ret = IMGLOAD_READ_ERROR;
      info_ptr = png_create_info_struct(png_ptr);
      if(!info_ptr)
         return false;

      png_set_bgr(png_ptr);
      png_set_expand(png_ptr);
      png_set_palette_to_rgb(png_ptr);
      png_set_strip_16(png_ptr);

      png_set_gray_to_rgb(png_ptr);
      png_set_read_fn(png_ptr, (void*)fl, &ReadFromCache);
      if(!png_read_info(png_ptr, info_ptr))
         return false;

      bpp = (info_ptr->pixel_depth+7) / 8;
      if(info_ptr->pixel_depth>32)
         bpp /= 2;
      //if(info_ptr->num_palette && info_ptr->bit_depth==8)
        // pf->bytes_per_pixel = 1;
                              //if 8-bit grayscale, consider it as RGB
      size_original_x = size_x = info_ptr->width;
      size_original_y = size_y = info_ptr->height;

      return true;
   }
Ejemplo n.º 9
0
static DFBResult
Probe( IDirectFBImageProvider_ProbeContext *ctx )
{
     if (png_check_sig( ctx->header, 8 ))
          return DFB_OK;

     return DFB_UNSUPPORTED;
}
Ejemplo n.º 10
0
int check_for_png (FILE *png_file) 
{
  rewind (png_file);
  if (fread (sigbytes, 1, sizeof(sigbytes), png_file) !=
      sizeof(sigbytes) ||
      (!png_check_sig (sigbytes, sizeof(sigbytes))))
    return 0;
  else
    return 1;
}
Ejemplo n.º 11
0
bool png_image_get_IHDR(const char *fn, uint32_t *width, uint32_t *height, uint8_t *bpp)
{
	stack_chain_iterate_t sci = { 0 };
	BYTE *file_buffer = nullptr;
	file_buffer_t file = { 0 };

	json_t *chain = resolve_chain_game(fn);

	if (json_array_size(chain)) {
		log_printf("(PNG) Resolving %s...", json_array_get_string(chain, 0));
		while (file_buffer == nullptr && stack_chain_iterate(&sci, chain, SCI_BACKWARDS, nullptr) != 0) {
			file_buffer = (BYTE*)patch_file_load(sci.patch_info, sci.fn, &file.size);
		}
	}
	if (!file_buffer) {
		log_print("not found\n");
		json_decref(chain);
		return false;
	}
	patch_print_fn(sci.patch_info, sci.fn);
	log_print("\n");
	json_decref(chain);
	file.buffer = file_buffer;

	if (!png_check_sig(file.buffer, 8)) {
		log_print("Bad PNG signature!\n");
		free(file_buffer);
		return false;
	}
	file.buffer += 8;
	file.size -= 8;

	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, png_error_callback, png_warning_callback);
	png_infop info_ptr = png_create_info_struct(png_ptr);
	if (setjmp(png_jmpbuf(png_ptr))) {
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		free(file_buffer);
		return false;
	}
	png_set_read_fn(png_ptr, &file, read_bytes);
	png_set_sig_bytes(png_ptr, 8);
	png_read_info(png_ptr, info_ptr);

	int color_type;
	png_get_IHDR(png_ptr, info_ptr, width, height, NULL, &color_type, NULL, NULL, NULL);
	if (bpp) {
		*bpp = (color_type & PNG_COLOR_MASK_ALPHA) ? 32 : 24;
	}

	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
	free(file_buffer);
	return true;
}
Ejemplo n.º 12
0
//
// Constructor
//
PNGReader::PNGReader(const QString & ext, MemoryFile & file)
	: ImageFormatReaderHelper(file)
{
	if (file.size() < 8)
		return;

	byte buf[8];
	if (!tryReadFile(buf, sizeof(buf)))
		return;

	if (png_check_sig((png_bytep)buf, sizeof(buf)))
		m_IsValid = true;
}
Ejemplo n.º 13
0
bool validate(SprigFile *pngFile) {
    
    //Allocate a buffer of 8 bytes, where we can put the file signature.
    png_byte header[8];
    
    fread(&header, 8, sizeof(png_byte), pngFile->file);
    rewind(pngFile->file);//rewind to prepare for reading the file
    
    if(!png_check_sig(header, 8))
    {
        return false;
    }
    
    return true;
}
Ejemplo n.º 14
0
	virtual bool opendata(const unsigned char *data, size_t size)
	{
		if (m_png_ptr)
			return false;
		if (size < 8)
			return false;
		if (png_check_sig(data, 8)){
			m_png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
			m_info_ptr = png_create_info_struct(m_png_ptr);
			m_data_ptr = new PNGData;
			m_data_ptr->pdata = (const unsigned char *)data;
			m_data_ptr->size = size;
			png_set_read_fn(m_png_ptr, m_data_ptr, data_from_memory);
			png_read_info(m_png_ptr, m_info_ptr);
			return true;
		}
		return false;
	}
Ejemplo n.º 15
0
/* check to see if a file is a png file using png_check_sig() */
int check_png(char * file_name)
{
   FILE *fp;
   char buf[8];
   int ret;

   fp = fopen(file_name, "rb");
   if (!fp)
      return 0;
   ret = fread(buf, 1, 8, fp);
   fclose(fp);

   if (ret != 8)
      return 0;

   ret = png_check_sig(buf, 8);

   return (ret);
}
Ejemplo n.º 16
0
Archivo: main.c Proyecto: pornel/dssim
static int read_image(const char *filename, png24_image *image)
{
    int retval=1;
    bool using_stdin = false;
    FILE *fh;
    unsigned char buffer[8];

    if (0 == strcmp("-", filename)) {
        using_stdin = true;
        fh = stdin;
    } else {
        fh = fopen(filename, "rb");
        if (!fh) {
            return 1;
        }
    }

    setvbuf(fh, (char *)buffer, _IOFBF, 8);

    // the first read fills the buffer up, but put char back on after
    int c = fgetc(fh);
    ungetc(c, fh);

    // the png number is not really precise but I guess the situation where this would falsely pass is almost equal to 0
    if (png_check_sig(buffer, 8))
    {
        /*
         Reads image into png24_image struct. Returns non-zero on error
         */
        retval = rwpng_read_image24(fh, image, 0);
    }
#ifdef USE_LIBJPEG
    else
    {
        retval=read_image_jpeg(fh,image);
    }
#endif
    if(!using_stdin) {
        fclose(fh);
    }
    return retval;
}
Ejemplo n.º 17
0
	virtual bool openfile(const char *filename)
	{
		if (m_png_ptr)
			return false;
		FILE *f = fopen(filename, "rb");
		if (f){
			unsigned char head[8];
			fread(head, 1, 8, f);
			if (png_check_sig(head, 8)){
				m_png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
				m_info_ptr = png_create_info_struct(m_png_ptr);
				png_init_io(m_png_ptr, f);
				png_set_sig_bytes(m_png_ptr, 8);
				png_read_info(m_png_ptr, m_info_ptr);
				m_file_ptr = f;
				return true;
			}
			fclose(f);
		}
		return false;
	}
Ejemplo n.º 18
0
Archivo: png2ctx.c Proyecto: ev3dev/grx
static gboolean querypng(FILE *f, int *w, int *h)
{
  png_struct *png_ptr = NULL;
  png_info *info_ptr = NULL;
  png_byte buf[8];
  png_uint_32 width;
  png_uint_32 height;
  int bit_depth;
  int color_type;

  /* is it a PNG file? */
  if( fread( buf,1,8,f ) != 8 ) return FALSE;
  if( ! png_check_sig( buf,8 ) ) return FALSE;

  png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
  if( !png_ptr ) return FALSE;

  info_ptr = png_create_info_struct( png_ptr );
  if( !info_ptr ){
    png_destroy_read_struct( &png_ptr,NULL,NULL );
    return FALSE;
    }

  if( setjmp( png_jmpbuf(png_ptr) ) ){
    png_destroy_read_struct( &png_ptr,&info_ptr,NULL );
    return FALSE;
    }

  png_init_io( png_ptr,f );
  png_set_sig_bytes( png_ptr,8 );
  png_read_info( png_ptr,info_ptr );

  png_get_IHDR( png_ptr,info_ptr,&width,&height,&bit_depth,
                &color_type,NULL,NULL,NULL);
  *w = width;
  *h = height;

  png_destroy_read_struct( &png_ptr,&info_ptr,NULL );
  return TRUE;
}
Ejemplo n.º 19
0
void * readpng_init(FILE *infile)
{
    uint8 sig[8];
    readpng_structs_t * strs = malloc(sizeof(readpng_structs_t));
    memset(strs, 0, sizeof(readpng_structs_t));

    /* first do a quick check that the file really is a PNG image; could
     * have used slightly more general png_sig_cmp() function instead */

    fread(sig, 1, 8, infile);
    if (!png_check_sig(sig, 8)) {
        free(strs);
        return NULL;   /* bad signature */
    }

    /* could pass pointers to user-defined error handlers instead of NULLs: */

    strs->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!strs->png_ptr) {
        free(strs);
        return NULL;   /* out of memory */
    }

    strs->info_ptr = png_create_info_struct(strs->png_ptr);
    if (!strs->info_ptr) {
        png_destroy_read_struct(&strs->png_ptr, NULL, NULL);
        free(strs);
        return NULL;   /* out of memory */
    }

    png_init_io(strs->png_ptr, infile);
    png_set_sig_bytes(strs->png_ptr, 8);  /* we already read the 8 signature bytes */

    png_read_info(strs->png_ptr, strs->info_ptr);  /* read all PNG info up to image data */

    /* OK, that's all we need for now; return happy */

    return (void *)strs;
}
Ejemplo n.º 20
0
int loadimage(char *filename)
{
	infile = fopen(filename, "rb");

	unsigned char sig[8];
  
    fread(sig, 1, 8, infile);
    if (!png_check_sig(sig, 8))
        return 1;   /* bad signature */

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL,
      NULL);
    if (!png_ptr)
        return 4;   /* out of memory */
  
    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        return 4;   /* out of memory */
    }

    if (setjmp(png_ptr->jmpbuf)) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return 2;
    }

	png_init_io(png_ptr, infile);
    png_set_sig_bytes(png_ptr, 8);
    png_read_info(png_ptr, info_ptr);



    //png_get_IHDR(png_ptr, info_ptr, &pwidth, &pheight, &bit_depth,
    //  &color_type, NULL, NULL, NULL);
    //*width = pwidth;
    //*height = pheight;
  
    return 0;
}
static Bool
readPngFileToImage (FILE *file,
		    int  *width,
		    int  *height,
		    void **data)
{
    unsigned char png_sig[PNG_SIG_SIZE];
    int		  sig_bytes;
    png_struct	  *png;
    png_info	  *info;
    Bool	  status;

    sig_bytes = fread (png_sig, 1, PNG_SIG_SIZE, file);
    if (png_check_sig (png_sig, sig_bytes) == 0)
	return FALSE;

    png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png)
	return FALSE;

    info = png_create_info_struct (png);
    if (!info)
    {
	png_destroy_read_struct (&png, NULL, NULL);

	return FALSE;
    }

    png_init_io (png, file);
    png_set_sig_bytes (png, sig_bytes);

    status = readPngData (png, info, data, width, height);

    png_destroy_read_struct (&png, &info, NULL);

    return status;
}
Ejemplo n.º 22
0
int gr3_readpngtomemory_(int *pixels, const char *pngfile, int width, int height) {
  FILE *png_fp;
  png_structp png_ptr;
  png_infop info_ptr = NULL;
  png_infop end_info = NULL;
  unsigned char sig[8];
  png_bytep *row_pointers;
  int i;
  png_fp = fopen(pngfile,"rb");
  if (!png_fp) {
    return 1;
  }
  i = fread(sig, 1, 8, png_fp);
  if (!png_check_sig(sig, 8)){
    return 2;
  }
  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  if (!png_ptr) {
    return 3;
  }
  info_ptr = png_create_info_struct(png_ptr);
  end_info = png_create_info_struct(png_ptr);
  if (!info_ptr || !end_info) {
    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
    return 4;
  }
  png_init_io(png_ptr, png_fp);
  png_set_sig_bytes(png_ptr, 8);
  png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
  row_pointers = png_get_rows(png_ptr, info_ptr);
  for (i = 0; i < height; i++) {
    memcpy(pixels+(height-1-i)*width,row_pointers[i],width*sizeof(int));
  }
  png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
  fclose(png_fp);
  return 0;
}
static Bool
readPngBuffer (const unsigned char *buffer,
	       char		   **data,
	       unsigned int	   *width,
	       unsigned int	   *height)
{
    unsigned char	png_sig[PNG_SIG_SIZE];
    png_struct		*png;
    png_info		*info;
    const unsigned char *b = buffer + PNG_SIG_SIZE;
    Bool		status;

    memcpy (png_sig, buffer, PNG_SIG_SIZE);
    if (png_check_sig (png_sig, PNG_SIG_SIZE) == 0)
	return FALSE;

    png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png)
	return FALSE;

    info = png_create_info_struct (png);
    if (!info)
    {
	png_destroy_read_struct (&png, NULL, NULL);
	return FALSE;
    }

    png_set_read_fn (png, (void *) &b, userReadData);
    png_set_sig_bytes (png, PNG_SIG_SIZE);

    status = readPngData (png, info, data, width, height);

    png_destroy_read_struct (&png, &info, NULL);

    return status;
}
Ejemplo n.º 24
0
static struct gl_texture_t *ReadPNGFromFile (const char *filename) {

  struct gl_texture_t *texinfo;
  png_byte magic[8];
  png_structp png_ptr;
  png_infop info_ptr;
  int bit_depth, color_type;
  FILE *fp = NULL;
  png_bytep *row_pointers = NULL;
  png_uint_32 w, h;
  int i;

  /* Open image file */
  fp = fopen (filename, "rb");
  if (!fp)
    {
      fprintf (stderr, "error: couldn't open \"%s\"!\n", filename);
      return NULL;
    }

  /* Read magic number */
  fread (magic, 1, sizeof (magic), fp);

  /* Check for valid magic number */
  if (!png_check_sig (magic, sizeof (magic)))
    {
      fprintf (stderr, "error: \"%s\" is not a valid PNG image!\n",
	       filename);
      fclose (fp);
      return NULL;
    }

  /* Create a png read struct */
  png_ptr = png_create_read_struct
    (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  if (!png_ptr)
    {
      fclose (fp);
      return NULL;
    }

  /* Create a png info struct */
  info_ptr = png_create_info_struct (png_ptr);
  if (!info_ptr)
    {
      fclose (fp);
      png_destroy_read_struct (&png_ptr, NULL, NULL);
      return NULL;
    }

  /* Create our OpenGL texture object */
  texinfo = (struct gl_texture_t *)
    malloc (sizeof (struct gl_texture_t));

  /* Initialize the setjmp for returning properly after a libpng
     error occured */
  if (setjmp (png_jmpbuf (png_ptr)))
    {
      fclose (fp);
      png_destroy_read_struct (&png_ptr, &info_ptr, NULL);

      if (row_pointers)
	free (row_pointers);

      if (texinfo)
	{
	  if (texinfo->texels)
	    free (texinfo->texels);

	  free (texinfo);
	}

      return NULL;
    }

  /* Setup libpng for using standard C fread() function
     with our FILE pointer */
  png_init_io (png_ptr, fp);

  /* Tell libpng that we have already read the magic number */
  png_set_sig_bytes (png_ptr, sizeof (magic));

  /* Read png info */
  png_read_info (png_ptr, info_ptr);

  /* Get some usefull information from header */
  bit_depth = png_get_bit_depth (png_ptr, info_ptr);
  color_type = png_get_color_type (png_ptr, info_ptr);

  /* Convert index color images to RGB images */
  if (color_type == PNG_COLOR_TYPE_PALETTE)
    png_set_palette_to_rgb (png_ptr);

  /* Convert 1-2-4 bits grayscale images to 8 bits
     grayscale. */
  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    png_set_gray_1_2_4_to_8 (png_ptr);

  if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
    png_set_tRNS_to_alpha (png_ptr);

  if (bit_depth == 16)
    png_set_strip_16 (png_ptr);
  else if (bit_depth < 8)
    png_set_packing (png_ptr);

  /* Update info structure to apply transformations */
  png_read_update_info (png_ptr, info_ptr);

  /* Retrieve updated information */
  png_get_IHDR (png_ptr, info_ptr, &w, &h, &bit_depth,
		&color_type, NULL, NULL, NULL);
  texinfo->width = w;
  texinfo->height = h;

  /* Get image format and components per pixel */
  GetPNGtextureInfo (color_type, texinfo);

  /* We can now allocate memory for storing pixel data */
  texinfo->texels = (GLubyte *)malloc (sizeof (GLubyte) * texinfo->width
	       * texinfo->height * texinfo->internalFormat);

  /* Setup a pointer array.  Each one points at the begening of a row. */
  row_pointers = (png_bytep *)malloc (sizeof (png_bytep) * texinfo->height);

  for (i = 0; i < texinfo->height; ++i)
    {
      row_pointers[i] = (png_bytep)(texinfo->texels +
	((texinfo->height - (i + 1)) * texinfo->width * texinfo->internalFormat));
    }

  /* Read pixel data using row pointers */
  png_read_image (png_ptr, row_pointers);

  /* Finish decompression and release memory */
  png_read_end (png_ptr, NULL);
  png_destroy_read_struct (&png_ptr, &info_ptr, NULL);

  /* We don't need row pointers anymore */
  free (row_pointers);

  fclose (fp);
  return texinfo;
}
Ejemplo n.º 25
0
	int Read ( const char *filename, byte **data, int *width, int *height )
	{
		// Setup the pointers
		*data = NULL;
		*width = 0;
		*height = 0;

		// Check and make sure the filename is valid (because you can never be too careful...)
		if( !filename || !filename[0] )
		{
			ri->Printf( PRINT_ERROR, "PNG read called with invalid filename.\n" );
			return 0;
		}

		// Copy the filename to the global variable
		Q_strncpyz( currentPNGFile, filename, sizeof(currentPNGFile) );

		// Make sure we're actually reading PNG data.
		const int SIGNATURE_LEN = 8;

		byte ident[SIGNATURE_LEN];
		memcpy (ident, buf, SIGNATURE_LEN);

		if ( !png_check_sig (ident, SIGNATURE_LEN) )
		{
			ri->Printf (PRINT_ERROR, "PNG signature not found in %s.\n", currentPNGFile );
			return 0;
		}

		png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, png_print_error, png_print_warning);
		if ( png_ptr == NULL )
		{
			ri->Printf (PRINT_ERROR, "PNG: Could not allocate enough memory to load %s\n", currentPNGFile );
			return 0;
		}

		info_ptr = png_create_info_struct (png_ptr);
		if ( setjmp (png_jmpbuf (png_ptr)) )
		{
			return 0;
		}

		// We've read the signature
		offset += SIGNATURE_LEN;

		// Setup reading information, and read header
		png_set_read_fn (png_ptr, (png_voidp)this, &user_read_data);
		png_set_sig_bytes (png_ptr, SIGNATURE_LEN);
		png_read_info (png_ptr, info_ptr);

		png_uint_32 width_;
		png_uint_32 height_;
		int depth;
		int colortype;

		png_get_IHDR (png_ptr, info_ptr, &width_, &height_, &depth, &colortype, NULL, NULL, NULL);

		// While modern OpenGL can handle non-PoT textures, it's faster to handle only PoT
		// so that the graphics driver doesn't have to fiddle about with the texture when uploading.
		if ( !IsPowerOfTwo (width_) || !IsPowerOfTwo (height_) )
		{
			ri->Printf (PRINT_ERROR, "PNG: Width or height of %s is not a power-of-two.\n", currentPNGFile );
			return 0;
		}

		// This function is equivalent to using what used to be LoadPNG32. LoadPNG8 also existed,
		// but this only seemed to be used by the RMG system which does not work in JKA. If this
		// does need to be re-implemented, then colortype should be PNG_COLOR_TYPE_PALETTE or
		// PNG_COLOR_TYPE_GRAY.
		if ( colortype != PNG_COLOR_TYPE_RGB && colortype != PNG_COLOR_TYPE_RGBA )
		{
			ri->Printf (PRINT_ERROR, "PNG: %s is not 24-bit or 32-bit.\n", currentPNGFile );
			return 0;
		}

		// Read the png data
		if ( colortype == PNG_COLOR_TYPE_RGB )
		{
			// Expand RGB -> RGBA
			png_set_add_alpha (png_ptr, 0xff, PNG_FILLER_AFTER);
		}

		png_read_update_info (png_ptr, info_ptr);

		// We always assume there are 4 channels. RGB channels are expanded to RGBA when read.
		byte *tempData = (byte *)ri->Z_Malloc (width_ * height_ * 4, TAG_TEMP_PNG, qfalse, 4);
		if ( !tempData )
		{
			ri->Printf (PRINT_ERROR, "Could not allocate enough memory to load %s.\n", currentPNGFile );
			return 0;
		}

		// Dynamic array of row pointers, with 'height' elements, initialized to NULL.
		byte **row_pointers = (byte **)ri->Hunk_AllocateTempMemory (sizeof (byte *) * height_);
		if ( !row_pointers )
		{
			ri->Printf (PRINT_ERROR, "Could not allocate enough memory to load %s.\n", currentPNGFile );

			ri->Z_Free (tempData);
			
			return 0;
		}

		// Re-set the jmp so that these new memory allocations can be reclaimed
		if ( setjmp (png_jmpbuf (png_ptr)) )
		{
			ri->Hunk_FreeTempMemory (row_pointers);
			ri->Z_Free (tempData);
			return 0;
		}

		for ( unsigned int i = 0, j = 0; i < height_; i++, j += 4 )
		{
			row_pointers[i] = tempData + j * width_;
		}

		png_read_image (png_ptr, row_pointers);

		// Finish reading
		png_read_end (png_ptr, NULL);

		ri->Hunk_FreeTempMemory (row_pointers);

		// Finally assign all the parameters
		*data = tempData;
		*width = width_;
		*height = height_;

		return 1;
	}
Ejemplo n.º 26
0
static bool doIsCorrectImageFormat(const byte *fileDataPtr, uint fileSize) {
	return (fileSize > 8) && png_check_sig(const_cast<byte *>(fileDataPtr), 8);
}
Ejemplo n.º 27
0
int
png_load(char *filename)
{
	int i,j,k;
	FILE *fd;
	u_char header[NUMBER];
	png_structp png_ptr;
	png_infop info_ptr,end_info;
	png_uint_32 width,height;
	int bit_depth,color_type,interlace_type;
	int compression_type,filter_type;
	int channels,rowbytes;
	double gamma;
	png_colorp palette;
	int num_palette;
	png_bytep *row_pointers;
	char c;
	int res=0;

	fd=fopen(filename,"rb");
	
	if(fd==NULL) {
		VGLEnd();
		perror("fopen");
		exit(1);
	}
	fread(header,1,NUMBER,fd);
	if(!png_check_sig(header,NUMBER)) {
		fprintf(stderr,"Not a PNG file.\n");
		return(-1);
	}
	png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING,(void *)NULL,
		NULL,NULL);
	info_ptr=png_create_info_struct(png_ptr);
	end_info=png_create_info_struct(png_ptr);
	if(!png_ptr || !info_ptr || !end_info) {
		VGLEnd();
		fprintf(stderr,"failed to allocate needed structs!\n");
		png_destroy_read_struct(&png_ptr,&info_ptr,&end_info);
		return(-1);
	}
	png_set_sig_bytes(png_ptr,NUMBER);
	png_init_io(png_ptr,fd);
	png_read_info(png_ptr,info_ptr);
	png_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth,
		&color_type,&interlace_type,&compression_type,&filter_type);
	png_get_PLTE(png_ptr,info_ptr,&palette,&num_palette);
	channels=png_get_channels(png_ptr,info_ptr);
	rowbytes=png_get_rowbytes(png_ptr,info_ptr);
	if(bit_depth==16)
		png_set_strip_16(png_ptr);
	if(color_type & PNG_COLOR_MASK_ALPHA) 
		png_set_strip_alpha(png_ptr);
	if(png_get_gAMA(png_ptr,info_ptr,&gamma))
		png_set_gamma(png_ptr,screen_gamma,gamma);
	else
	png_set_gamma(png_ptr,screen_gamma,0.45);
	if(res==0) {
		/* Dither */
		if(color_type & PNG_COLOR_MASK_COLOR) {
			if(png_get_valid(png_ptr,info_ptr,PNG_INFO_PLTE)) {
				png_uint_16p histogram;
				png_get_hIST(png_ptr,info_ptr,&histogram);
				png_set_dither(png_ptr,palette,num_palette,max_screen_colors,histogram,0);
			} else {
				png_color std_color_cube[16]={
					{0x00,0x00,0x00},
					{0x02,0x02,0x02},
					{0x04,0x04,0x04},
					{0x06,0x06,0x06},
					{0x08,0x08,0x08},
					{0x0a,0x0a,0x0a},
					{0x0c,0x0c,0x0c},
					{0x0e,0x0e,0x0e},
					{0x10,0x10,0x10},
					{0x12,0x12,0x12},
					{0x14,0x14,0x14},
					{0x16,0x16,0x16},
					{0x18,0x18,0x18},
					{0x1a,0x1a,0x1a},
					{0x1d,0x1d,0x1d},
					{0xff,0xff,0xff},
				};
				png_set_dither(png_ptr,std_color_cube,max_screen_colors,max_screen_colors,NULL,0);
			}
		}
	}
	png_set_packing(png_ptr);
	if(png_get_valid(png_ptr,info_ptr,PNG_INFO_sBIT)) {
		png_color_8p sig_bit;

		png_get_sBIT(png_ptr,info_ptr,&sig_bit);
		png_set_shift(png_ptr,sig_bit);
	}
	png_read_update_info(png_ptr,info_ptr);
	png_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth,
		&color_type,&interlace_type,&compression_type,&filter_type);
	png_get_PLTE(png_ptr,info_ptr,&palette,&num_palette);
	channels=png_get_channels(png_ptr,info_ptr);
	rowbytes=png_get_rowbytes(png_ptr,info_ptr);
	row_pointers=malloc(height*sizeof(png_bytep));
	for(i=0;i<height;i++) {
		row_pointers[i]=malloc(rowbytes);
	}
	png_read_image(png_ptr,row_pointers);
	png_read_end(png_ptr,end_info);
	png_destroy_read_struct(&png_ptr,&info_ptr,&end_info);
	fclose(fd);
	/* Set palette */
	if(res) k=2;
	else k=2;
	for(i=0;i<256;i++) {
	 	pal_red[i]=255;
	 	pal_green[i]=255;
	 	pal_blue[i]=255;
	}
	for(i=0;i<num_palette;i++) {
	 	pal_red[i]=(palette+i)->red>>k;
	 	pal_green[i]=(palette+i)->green>>k;
	 	pal_blue[i]=(palette+i)->blue>>k;
	}
	pal_colors=num_palette;
	if(pic.Bitmap!=NULL) free(pic.Bitmap);
	pic.Bitmap=(byte *)calloc(rowbytes*height,sizeof(byte));
	pic.Type=MEMBUF;
	pic.Xsize=rowbytes;
	pic.Ysize=height;
	for(i=0;i<rowbytes;i++) {
		for(j=0;j<height;j++) {
			VGLSetXY(&pic,
			i,j,row_pointers[j][i]);
		}
	}
	a.zoom=1;
	a.Xshift=(VGLDisplay->Xsize-pic.Xsize)/2;
	a.Yshift=(VGLDisplay->Ysize-pic.Ysize)/2;
	a.rotate=0;
	return(0);
}
Ejemplo n.º 28
0
ImageReaderPNG::ImageType ImageReaderPNG::readData(const std::string& filePath, PNGInfra& infra, bool wantAlpha)
{
	if (filePath.empty())
		return eInvalid;

	infra.pFile = fopen(filePath.c_str(), "rb");
	if (!infra.pFile)
	{
		fprintf(stderr, "Error opening file: %s\n", filePath.c_str());
		return eInvalid;
	}

	unsigned char sig[8];

	// check the signature
	fread(sig, 1, 8, infra.pFile);
	if (!png_check_sig(sig, 8))
	{
		fprintf(stderr, "Cannot open file: %s - not a valid PNG file.\n", filePath.c_str());
		fclose(infra.pFile);
		return eInvalid;
	}

	infra.pPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (!infra.pPNG)
	{
		fclose(infra.pFile);
		return eInvalid;
	}

	infra.pInfo = png_create_info_struct(infra.pPNG);
	if (!infra.pInfo)
	{
		png_destroy_read_struct(&infra.pPNG, NULL, NULL);
		fclose(infra.pFile);
		return eInvalid;
	}

	if (setjmp(png_jmpbuf(infra.pPNG)))
	{
		png_destroy_read_struct(&infra.pPNG, &infra.pInfo, NULL);
		fclose(infra.pFile);
		return eInvalid;
	}

	png_init_io(infra.pPNG, infra.pFile);
	png_set_sig_bytes(infra.pPNG, 8);
	png_read_info(infra.pPNG, infra.pInfo);

	int colorType;
	int bitDepth, interlaceType, compressionType;

	png_get_IHDR(infra.pPNG, infra.pInfo, &infra.width, &infra.height, &bitDepth, &colorType, &interlaceType, &compressionType, NULL);

	if (colorType == PNG_COLOR_TYPE_PALETTE)
		png_set_palette_to_rgb(infra.pPNG);

	if (png_get_valid(infra.pPNG, infra.pInfo, PNG_INFO_tRNS))
	{
		png_set_tRNS_to_alpha(infra.pPNG);
	}

	if (bitDepth == 16)
		png_set_strip_16(infra.pPNG);

	ImageType type = eInvalid;

	if (!wantAlpha)
	{
		// add black Alpha
		if ((colorType & PNG_COLOR_MASK_ALPHA) == 0)
			png_set_add_alpha(infra.pPNG, 0xFF, PNG_FILLER_AFTER);

		if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
			png_set_gray_to_rgb(infra.pPNG);
		else if (colorType != PNG_COLOR_TYPE_RGB && colorType != PNG_COLOR_TYPE_RGB_ALPHA)
			return eInvalid;

		type = eRGBA;
	}
	else
	{
		if (colorType == PNG_COLOR_TYPE_RGB_ALPHA)
			type = eRGBA;
		else if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
			type = eA;
		else
			return eInvalid;
	}

	png_read_update_info(infra.pPNG, infra.pInfo);

	infra.pRows = new png_bytep[infra.height * png_sizeof(png_bytep)];

	png_set_rows(infra.pPNG, infra.pInfo, infra.pRows);

	for (unsigned int i = 0; i < infra.height; i++)
	{
		infra.pRows[i] = new png_byte[png_get_rowbytes(infra.pPNG, infra.pInfo)];
	}

	png_read_image(infra.pPNG, infra.pRows);
	png_read_end(infra.pPNG, infra.pInfo);

	return type;
}
Ejemplo n.º 29
0
APNGDATA * loadPng(IPngReader *pSrc)
{
	png_bytep  dataFrame;
	png_uint_32 bytesPerRow;
	png_uint_32 bytesPerFrame;
    png_bytepp rowPointers;
	png_byte   sig[8];
	
	png_structp png_ptr_read;
	png_infop info_ptr_read;
	
    pSrc->read(sig,8);
    if(!png_check_sig(sig,8))
    {
        return NULL;
    }
    
    png_ptr_read = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

    info_ptr_read = png_create_info_struct(png_ptr_read);
    
	if (setjmp(png_jmpbuf(png_ptr_read)))
    {
        png_destroy_read_struct(&png_ptr_read, &info_ptr_read, NULL);
        return NULL;
    }
        
    png_set_read_fn(png_ptr_read,pSrc,mypng_read_data);
    png_set_sig_bytes(png_ptr_read, 8);
 
    if ((png_ptr_read->bit_depth < 8) ||
        (png_ptr_read->color_type == PNG_COLOR_TYPE_PALETTE) ||
        (info_ptr_read->valid & PNG_INFO_tRNS))
        png_set_expand(png_ptr_read);

    png_set_add_alpha(png_ptr_read, 0xff, PNG_FILLER_AFTER);
    png_set_interlace_handling(png_ptr_read);
    png_set_gray_to_rgb(png_ptr_read);
    png_set_strip_16(png_ptr_read);
   
	png_read_info(png_ptr_read, info_ptr_read);
    png_read_update_info(png_ptr_read, info_ptr_read);
    
    bytesPerRow = png_ptr_read->width * 4;
    bytesPerFrame = bytesPerRow * png_ptr_read->height;
    
    APNGDATA * apng = (APNGDATA*) malloc(sizeof(APNGDATA));
    memset(apng,0,sizeof(APNGDATA));
    apng->nWid  = png_ptr_read->width;
    apng->nHei = png_ptr_read->height;
    
    //图像帧数据
    dataFrame = (png_bytep)malloc(bytesPerRow * apng->nHei);
    memset(dataFrame,0,bytesPerFrame);
    //获得扫描行指针
    rowPointers = (png_bytepp)malloc(sizeof(png_bytep)* apng->nHei);
    for(int i=0;i<apng->nHei;i++)
        rowPointers[i] = dataFrame + bytesPerRow * i;

	if (!png_get_valid(png_ptr_read, info_ptr_read, PNG_INFO_acTL))
	{//load png doesn't has this trunk.
        
        png_read_image(png_ptr_read,rowPointers);
                
        apng->pdata =dataFrame;
        apng->nFrames =1;
	}else
	{//load apng
        apng->nFrames  = png_get_num_frames(png_ptr_read, info_ptr_read);//获取总帧数

        png_bytep data = (png_bytep)malloc( bytesPerFrame * apng->nFrames);//为每一帧分配内存
        png_bytep curFrame = (png_bytep)malloc(bytesPerFrame);
        memset(curFrame,0,bytesPerFrame);
               
        apng->nLoops = png_get_num_plays(png_ptr_read, info_ptr_read);
        apng->pDelay = (unsigned short*)malloc(sizeof(unsigned short)*apng->nFrames);
        
        for(int iFrame = 0;iFrame<apng->nFrames;iFrame++)
        {
            //读帧信息头
            png_read_frame_head(png_ptr_read, info_ptr_read);
            
            //计算出帧延时信息
            if (png_get_valid(png_ptr_read, info_ptr_read, PNG_INFO_fcTL))
            {
                png_uint_16 delay_num = info_ptr_read->next_frame_delay_num,
                            delay_den = info_ptr_read->next_frame_delay_den;
            
                if (delay_den==0 || delay_den==100)
                    apng->pDelay[iFrame] = delay_num;
                else
                    if (delay_den==10)
                        apng->pDelay[iFrame] = delay_num*10;
                    else
                        if (delay_den==1000)
                            apng->pDelay[iFrame] = delay_num/10;
                        else
                            apng->pDelay[iFrame] = delay_num*100/delay_den;
            }else
            {
                apng->pDelay[iFrame] = 0;
            }
            //读取PNG帧到dataFrame中,不含偏移数据
            png_read_image(png_ptr_read, rowPointers);
            {//将当前帧数据绘制到当前显示帧中:1)获得绘制的背景;2)计算出绘制位置; 3)使用指定的绘制方式与背景混合


                //1)计算出绘制位置
                png_bytep lineDst=curFrame+info_ptr_read->next_frame_y_offset*bytesPerRow + 4 * info_ptr_read->next_frame_x_offset;
                png_bytep lineSour=dataFrame;
                //2)使用指定的绘制方式与背景混合
                switch(info_ptr_read->next_frame_blend_op)
                {
                case PNG_BLEND_OP_OVER:
                    {
                        for(unsigned int y=0;y<info_ptr_read->next_frame_height;y++)
                        {
                            png_bytep lineDst1=lineDst;
                            png_bytep lineSour1=lineSour;
                            for(unsigned int x=0;x<info_ptr_read->next_frame_width;x++)
                            {
                                png_byte alpha = lineSour1[3];
                                *lineDst1++ = ((*lineDst1)*(255-alpha)+(*lineSour1++)*alpha)>>8;
                                *lineDst1++ = ((*lineDst1)*(255-alpha)+(*lineSour1++)*alpha)>>8;
                                *lineDst1++ = ((*lineDst1)*(255-alpha)+(*lineSour1++)*alpha)>>8;
                                *lineDst1++ = ((*lineDst1)*(255-alpha)+(*lineSour1++)*alpha)>>8;
                            }
                            lineDst += bytesPerRow;
                            lineSour+= bytesPerRow;
                        }
                    }
                    break;
                case PNG_BLEND_OP_SOURCE:
                    {
                        for(unsigned int  y=0;y<info_ptr_read->next_frame_height;y++)
                        {
                            memcpy(lineDst,lineSour,info_ptr_read->next_frame_width*4);
                            lineDst += bytesPerRow;
                            lineSour+= bytesPerRow;
                        }
                    }
                    break;
                default:
                    SASSERT(FALSE);
                    break;
                }
                
                png_bytep targetFrame = data + bytesPerFrame * iFrame;
                memcpy(targetFrame,curFrame,bytesPerFrame);

                lineDst=curFrame+info_ptr_read->next_frame_y_offset*bytesPerRow + 4 * info_ptr_read->next_frame_x_offset;

                //3)处理当前帧绘制区域
                switch(info_ptr_read->next_frame_dispose_op)
                {
                case PNG_DISPOSE_OP_BACKGROUND://clear background
                    {
                        for(unsigned int y=0;y<info_ptr_read->next_frame_height;y++)
                        {
                            memset(lineDst,0,info_ptr_read->next_frame_width*4);
                            lineDst += bytesPerRow;
                        }

                    }
                    break;
                case PNG_DISPOSE_OP_PREVIOUS://copy previous frame
                    if(iFrame>0)
                    {
                        memcpy(curFrame,targetFrame-bytesPerFrame,bytesPerFrame);
                    }
                    break;
                case PNG_DISPOSE_OP_NONE://using current frame, doing nothing
                    break;
                default:
                    SASSERT(0);
                    break;
                }
            }

        }
        free(curFrame);
        free(dataFrame);
        apng->pdata =data;
	}
    free(rowPointers);

	png_read_end(png_ptr_read,info_ptr_read);
	
    png_destroy_read_struct(&png_ptr_read, &info_ptr_read, NULL);
    return apng;    
}
Ejemplo n.º 30
0
main(int argc, char** argv)
{
	char* cmd=argv[0];
	char* pngfile=0;
	char* ppmfile;
	char* pgmfile;
	char* ext;
	char header[8];
	FILE *png;
	FILE *ppm;
	FILE *pgm;
	png_structp png_ptr;
	png_infop info_ptr;
	png_infop end_info;
	png_bytep* row_pointers;
	int h;
	int crop=0;
	int hotspot=0;
	int arg;

	for (arg=1; arg<argc; arg++) {
		if (0==strcmp(argv[arg],"-c")) {
			crop=1;
		} else if (0==strcmp(argv[arg],"-h")) {
			hotspot=1;
		} else {
			if (!pngfile) {
				pngfile=argv[arg];
			} else {
				fprintf(stderr,"Usage:  %s [-c] [-h] filename.png\n",cmd);
				fprintf(stderr,"  Reads filename.png then writes filename.ppm and filename.pgm\n");
				fprintf(stderr,"     filename.ppm is non-alpha image\n");
				fprintf(stderr,"     filename.pgm is alpha image\n");
				fprintf(stderr,"  -c causes auto-cropping to non-transparent rectangle\n");
				fprintf(stderr,"  -h causes HOTSPOT comment in PPM file, center of original\n");
				exit(1);
			}
		}
	}

	ppmfile=strdup(pngfile);
	ext=strstr(ppmfile,".png");
	if (!ext) {
		fprintf(stderr,"%s:  PNG file must have extension .png\n");
		exit(1);
	}
	strcpy(ext,".ppm");
	pgmfile=strdup(pngfile);
	ext=strstr(pgmfile,".png");
	strcpy(ext,".pgm");

	ppm = fopen(ppmfile, "wb");
	if (!ppm) { perror(ppmfile); exit(1); }
	pgm = fopen(pgmfile, "wb");
	if (!pgm) { perror(pgmfile); exit(1); }

	/* Boilerplater PNG access code [gee I hate C] */

	png = fopen(pngfile, "rb");
	if (!png) { perror(pngfile); exit(1); }
	fread(header, 1, 8, png);
	if (!png_check_sig(header, 8)) {
		fprintf(stderr,"%s:  %s is not a valid PNG file\n",cmd,pngfile);
		exit(1);
	}
	fseek(png,0,SEEK_SET);

	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);
	if (!png_ptr) exit(1);

	info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr) exit(1);

	end_info = png_create_info_struct(png_ptr);
	if (!end_info) exit(1);

	png_init_io(png_ptr, png);

	png_read_info(png_ptr, info_ptr);

	if (info_ptr->channels!=4) {
		fprintf(stderr,"%s:  found %d channels, expected 4\n",cmd,info_ptr->channels);
		exit(1);
	}

	if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
		info_ptr->bit_depth < 8)
	png_set_expand(png_ptr);

	if (info_ptr->valid & PNG_INFO_tRNS)
	png_set_expand(png_ptr);

	if (info_ptr->bit_depth == 16)
		png_set_strip_16(png_ptr);

	if (info_ptr->bit_depth < 8)
		png_set_packing(png_ptr);

	png_read_update_info(png_ptr, info_ptr);

	row_pointers=(png_bytep*)malloc(sizeof(png_bytep)*info_ptr->height);
	{
		int y;
		for (y=0; y<info_ptr->height; y++) {
			row_pointers[y]=(unsigned char*)malloc(info_ptr->rowbytes);
		}
	}
	png_read_image(png_ptr, row_pointers);

	{
		int top,bottom;
		int left,right;
		int opaque=0;
		int y;

		if (crop) {
			for (left=0; left<info_ptr->width*4-4 && !opaque; left+=4) {
				for (y=0; y<info_ptr->height && !opaque; y++) {
					if (row_pointers[y][left+3]!=0) opaque=1;
				}
			}
			left-=4;
			opaque=0;
			for (right=info_ptr->width*4-4; right>=0 && !opaque; right-=4) {
				for (y=0; y<info_ptr->height && !opaque; y++) {
					if (row_pointers[y][right+3]!=0) opaque=1;
				}
			}
			right+=4;
			opaque=0;
			for (top=0; top<info_ptr->height && !opaque; top++) {
				int x;
				for (x=left; x<=right && !opaque; x+=4) {
					if (row_pointers[top][x+3]!=0) opaque=1;
				}
			}
			top--;
			opaque=0;
			for (bottom=info_ptr->height-1; bottom>=0 && !opaque; bottom--) {
				int x;
				for (x=left; x<=right && !opaque; x+=4) {
					if (row_pointers[bottom][x+3]!=0) opaque=1;
				}
			}
			bottom++;
		} else {
			top=left=0;
			right=info_ptr->width*4-4;
			bottom=info_ptr->height-1;
		}

		if (hotspot)
			fprintf(ppm,"P6\n# HOTSPOT %d %d\n%d %d\n%d\n",
				info_ptr->width/2-left/4,info_ptr->height/2-top,
				right/4-left/4+1,bottom-top+1,255);
		else
			fprintf(ppm,"P6\n%d %d\n%d\n",
				right/4-left/4+1,bottom-top+1,255);
		fprintf(pgm,"P5\n%d %d\n%d\n",right/4-left/4+1,bottom-top+1,255);

		for (y=top; y<=bottom; y++) {
			int x;
			for (x=left; x<=right; x+=4) {
				fwrite(row_pointers[y]+x,1,3,ppm);
				fwrite(row_pointers[y]+x+3,1,1,pgm);
			}
		}
	}

	fclose(ppm);
	fclose(pgm);

	png_read_end(png_ptr, end_info);
	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
}