Ejemplo n.º 1
0
bool PngLoader::basicImageLoad() {
	DEBUG_ENTER_FUNC();
	_pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (!_pngPtr)
		return false;

	png_set_error_fn(_pngPtr, (png_voidp) NULL, (png_error_ptr) NULL, warningFn);

	_infoPtr = png_create_info_struct(_pngPtr);
	if (!_infoPtr) {
		png_destroy_read_struct(&_pngPtr, png_infopp_NULL, png_infopp_NULL);
		return false;
	}
	// Set the png lib to use our read function
	png_set_read_fn(_pngPtr, &_file, libReadFunc);

	unsigned int sig_read = 0;

	png_set_sig_bytes(_pngPtr, sig_read);
	png_read_info(_pngPtr, _infoPtr);
	int interlaceType;
	png_get_IHDR(_pngPtr, _infoPtr, (png_uint_32 *)&_width, (png_uint_32 *)&_height, &_bitDepth,
		&_colorType, &interlaceType, int_p_NULL, int_p_NULL);
	_channels = png_get_channels(_pngPtr, _infoPtr);

	if (_colorType & PNG_COLOR_MASK_PALETTE)
		_paletteSize = _infoPtr->num_palette;

	return true;
}
Ejemplo n.º 2
0
decoder::decoder(std::streambuf *sbuf, info &i)
  : input_(sbuf),
    png_(png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0)),
    info_(png_create_info_struct(png_)),
    end_(png_create_info_struct(png_))
{
  png_byte header[magic_];
  input_->sgetn((char*)header, magic_);
  if (png_sig_cmp(header, 0, magic_)) throw std::runtime_error("Not a PNG file");

  png_set_sig_bytes(png_, magic_);
  png_set_read_fn(png_, input_, decoder_read);
  png_set_error_fn(png_, input_, decoder_error, decoder_warning);
  png_set_read_status_fn(png_, 0);
  png_read_info(png_, info_);
  png_uint_32 w, h;
  int d, c, in, co, f;
  png_get_IHDR(png_, info_, &w, &h, &d, &c, &in, &co, &f);  
  i.width = w;
  i.height = h;
  i.rowbytes = png_get_rowbytes(png_, info_);
  i.depth = d;
  i.colortype = static_cast<color_type>(c);
  i.compression = co;
  i.filter = f;
  i.interlace = static_cast<interlace_type>(in);
}
Ejemplo n.º 3
0
/* Load a PNG file from disk, doing colour coversion if required.
 */
ALLEGRO_BITMAP *_al_load_png_f(ALLEGRO_FILE *fp, int flags)
{
   jmp_buf jmpbuf;
   ALLEGRO_BITMAP *bmp;
   png_structp png_ptr;
   png_infop info_ptr;

   ALLEGRO_ASSERT(fp);

   if (!check_if_png(fp)) {
      ALLEGRO_ERROR("Not a png.\n");
      return NULL;
   }

   /* Create and initialize the png_struct with the desired error handler
    * functions.  If you want to use the default stderr and longjump method,
    * you can supply NULL for the last three parameters.  We also supply the
    * the compiler header file version, so that we know if the application
    * was compiled with a compatible version of the library.
    */
   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
                                    (void *)NULL, NULL, NULL);
   if (!png_ptr) {
      ALLEGRO_ERROR("png_ptr == NULL\n");
      return NULL;
   }

   /* Allocate/initialize the memory for image information. */
   info_ptr = png_create_info_struct(png_ptr);
   if (!info_ptr) {
      png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
      ALLEGRO_ERROR("png_create_info_struct failed\n");
      return NULL;
   }

   /* Set error handling. */
   if (setjmp(jmpbuf)) {
      /* Free all of the memory associated with the png_ptr and info_ptr */
      png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
      /* If we get here, we had a problem reading the file */
      ALLEGRO_ERROR("Error reading PNG file\n");
      return NULL;
   }
   png_set_error_fn(png_ptr, jmpbuf, user_error_fn, NULL);

   /* Use Allegro packfile routines. */
   png_set_read_fn(png_ptr, fp, (png_rw_ptr) read_data);

   /* We have already read some of the signature. */
   png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);

   /* Really load the image now. */
   bmp = really_load_png(png_ptr, info_ptr, flags);

   /* Clean up after the read, and free any memory allocated. */
   png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);

   return bmp;
}
Ejemplo n.º 4
0
static bool png_create(Fl_IO &png_io, uint8 *&data, Fl_PixelFormat &fmt, int &w, int &h)
{
    w=0, h=0;

    png_structp png_ptr = 0;
    png_infop info_ptr = 0, end_info_ptr = 0;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if(!png_ptr) { return_error(); }

    info_ptr = png_create_info_struct(png_ptr);
    if(!info_ptr) { return_error(); }

    end_info_ptr = png_create_info_struct(png_ptr);
    if(!end_info_ptr) { return_error(); }

    png_bytepp rows = 0;
    if(setjmp(png_ptr->jmpbuf)) {
        if(rows) free(rows);
        if(png_ptr) png_destroy_read_struct (&png_ptr, &info_ptr, &end_info_ptr);
        fputs((const char *)png_last_error, stderr);
        return false;
    }

    int ctype = 0;
    int pitch=0, bitspp=0;
    int ckey = -1;
    int i=0;
    uint32 Rmask=0, Gmask=0, Bmask=0, Amask=0;
    png_color_16 *transv=0;
    Fl_Colormap *palette=0;

    png_set_error_fn(png_ptr, (png_voidp)0, my_png_error, my_png_warning);
    png_set_read_fn(png_ptr, (png_voidp)&png_io, read_data_fn);

    png_read_info(png_ptr, info_ptr);

    if(!setup_png_transformations(png_ptr, info_ptr, transv, ctype, ckey, bitspp, w, h))
        goto error;
    if(ctype != PNG_COLOR_TYPE_PALETTE) {
#if !WORDS_BIGENDIAN
        Rmask = 0x000000FF;
        Gmask = 0x0000FF00;
        Bmask = 0x00FF0000;
        Amask = (info_ptr->channels == 4) ? 0xFF000000 : 0;
#else
        int s = (info_ptr->channels == 4) ? 0 : 8;
        Rmask = 0xFF000000 >> s;
        Gmask = 0x00FF0000 >> s;
        Bmask = 0x0000FF00 >> s;
        Amask = 0x000000FF >> s;
#endif
        if(info_ptr->channels == 4)
            fmt.masktype = FL_MASK_ALPHA;
    }
Ejemplo n.º 5
0
encoder::encoder(std::streambuf *sb, info const &i)
  : output_(sb),
    png_(png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0)),
    info_(png_create_info_struct(png_))
{
  png_set_write_fn(png_, output_, encoder_write, encoder_flush);
  png_set_error_fn(png_, output_, encoder_error, encoder_warning);
  png_set_write_status_fn(png_, 0);

  png_set_IHDR(png_, info_,
	       i.width, i.height, i.depth, i.colortype,
	       i.interlace, i.compression, i.filter);
}
Ejemplo n.º 6
0
/* Initialize png_ptr structure, and allocate any memory needed */
png_structp
png_create_write_struct(png_const_charp user_png_ver, voidp error_ptr,
   png_error_ptr error_fn, png_error_ptr warn_fn)
{
   png_structp png_ptr;
#ifdef USE_FAR_KEYWORD
   jmp_buf jmpbuf;
#endif
   png_debug(1, "in png_create_write_struct\n");
   if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL)
   {
      return (png_structp)NULL;
   }
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
#else
   if (setjmp(png_ptr->jmpbuf))
#endif
   {
      png_free(png_ptr, png_ptr->zbuf);
      png_destroy_struct(png_ptr);
      return (png_structp)NULL;
   }
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
#endif
   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);

   /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
    * we must recompile any applications that use any older library version.
    * For versions after libpng 1.0, we will be compatible, so we need
    * only check the first digit.
    */
   if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
       (png_libpng_ver[0] == '0' && user_png_ver[2] < '9'))
   {
      png_error(png_ptr,
         "Incompatible libpng version in application and library");
   }

   /* initialize zbuf - compression buffer */
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
   png_ptr->zbuf = png_malloc(png_ptr, png_ptr->zbuf_size);

   png_set_write_fn(png_ptr, NULL, NULL, NULL);

   return (png_ptr);
}
Ejemplo n.º 7
0
void PNGImageCodec::Save(OutputStreamPtr& file, const ImageParams& params,
		const ImageData& data) {
	OutputStream* writr = file.GetPtr();
	if (data.format != PixelFormat::BGRA8 && data.format != PixelFormat::RGBA8)
		// todo support formats like rgba16 etc.
		NEX_THROW_FatalError(EXCEPT_NOT_IMPLEMENTED);
	png_structp pngPtr = nullptr;
	png_infop infoPtr = nullptr;
	png_byte ** rowPointers = nullptr;

	// todo Fix for 64
	uint32 bitDepth = 32;
	size_t rowStride = data.width * bitDepth;
	bool flip = (data.format == PixelFormat::BGRA8);

	pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (pngPtr == nullptr)
		goto failed;
	infoPtr = png_create_info_struct(pngPtr);
	if (infoPtr == nullptr)
		goto failed;

	png_set_error_fn(pngPtr, (void *) (writr), PngWarn, PngWarn);
	png_set_write_fn(pngPtr, (void *) (writr), PngWriteFile, PngFlushFile);

	png_set_IHDR(pngPtr, infoPtr, data.width, data.height, bitDepth, // assumed
			PNG_COLOR_TYPE_RGB_ALPHA,
			PNG_INTERLACE_NONE,
			PNG_COMPRESSION_TYPE_DEFAULT,
			PNG_FILTER_TYPE_DEFAULT);
	rowPointers = (png_byte**) NEX_ALLOC(sizeof(png_byte*) * data.height,
			MEMCAT_GENERAL);

	for (uint32 i = 0; i < data.height; ++i) {
		rowPointers[i] = (static_cast<uint8*>(data.data)) + i * rowStride;
	}
	png_set_rows(pngPtr, infoPtr, rowPointers);
	png_write_png(pngPtr, infoPtr,
			flip ? PNG_TRANSFORM_BGR : PNG_TRANSFORM_IDENTITY, NULL);

	failed: if (rowPointers)
		NEX_FREE(rowPointers, MEMCAT_GENERAL);
	if (pngPtr)
		png_destroy_write_struct(&pngPtr, &infoPtr);
}
Ejemplo n.º 8
0
void _gTexLoadPNG(FILE* fp, gImage* tex)
{
  png_structp png_ptr;
  png_infop info_ptr;
  unsigned int sig_read = 0;
  png_uint_32 width, height;
  int bit_depth, color_type, interlace_type, x, y;
  u32* line;
  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
  png_set_error_fn(png_ptr,NULL,NULL,NULL);
  info_ptr = png_create_info_struct(png_ptr);
  png_init_io(png_ptr,fp);
  png_set_sig_bytes(png_ptr,sig_read);
  png_read_info(png_ptr,info_ptr);
  png_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth,&color_type,
                                &interlace_type,NULL,NULL);
  png_set_strip_16(png_ptr);
  png_set_packing(png_ptr);
  if (color_type == PNG_COLOR_TYPE_PALETTE)
    png_set_palette_to_rgb(png_ptr);
  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);
  png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
  tex->w = width;
  tex->h = height;
  tex->tw = _getNextPower2(width);
  tex->th = _getNextPower2(height);
  tex->ratio = (float)width / height;
  tex->data = memalign(16, tex->tw * tex->th * sizeof(gColor));
  line = malloc(width * 4);
  for (y = 0; y < height; y++) {
    png_read_row(png_ptr, (u8*) line, png_bytep_NULL);
    for (x = 0; x < width; x++) {
      u32 color = line[x];
      tex->data[x + y * tex->tw] =  color;
    }
  }
  free(line);
  png_read_end(png_ptr, info_ptr);
  png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
}
Ejemplo n.º 9
0
bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngHeader()
{
    state = Error;
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);
    if (!png_ptr)
        return false;

    png_set_error_fn(png_ptr, 0, 0, qt_png_warning);

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr, 0, 0);
        png_ptr = 0;
        return false;
    }

    end_info = png_create_info_struct(png_ptr);
    if (!end_info) {
        png_destroy_read_struct(&png_ptr, &info_ptr, 0);
        png_ptr = 0;
        return false;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        png_ptr = 0;
        return false;
    }

    png_set_read_fn(png_ptr, this, iod_read_fn);
    png_read_info(png_ptr, info_ptr);

    readPngTexts(info_ptr);

    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) {
        double file_gamma = 0.0;
        png_get_gAMA(png_ptr, info_ptr, &file_gamma);
        fileGamma = file_gamma;
    }

    state = ReadHeader;
    return true;
}
Ejemplo n.º 10
0
void png_reader<T>::init()
{
    png_byte header[8];
    std::memset(header,0,8);
    stream_.read(reinterpret_cast<char*>(header),8);
    if ( stream_.gcount() != 8)
    {
        throw image_reader_exception("PNG reader: Could not read image");
    }
    int is_png=!png_sig_cmp(header,0,8);
    if (!is_png)
    {
        throw image_reader_exception("File or stream is not a png");
    }
    png_structp png_ptr = png_create_read_struct
        (PNG_LIBPNG_VER_STRING,0,0,0);

    if (!png_ptr)
    {
        throw image_reader_exception("failed to allocate png_ptr");
    }

    // catch errors in a custom way to avoid the need for setjmp
    png_set_error_fn(png_ptr, png_get_error_ptr(png_ptr), user_error_fn, user_warning_fn);

    png_infop info_ptr;
    png_struct_guard sguard(&png_ptr,&info_ptr);
    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) throw image_reader_exception("failed to create info_ptr");

    png_set_read_fn(png_ptr, (png_voidp)&stream_, png_read_data);

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

    png_uint_32  width, height;
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth_, &color_type_,0,0,0);
    has_alpha_ = (color_type_ & PNG_COLOR_MASK_ALPHA) || png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS);
    width_=width;
    height_=height;

    MAPNIK_LOG_DEBUG(png_reader) << "png_reader: bit_depth=" << bit_depth_ << ",color_type=" << color_type_;
}
Ejemplo n.º 11
0
static nserror nspng_create_png_data(nspng_content *png_c)
{
	union content_msg_data msg_data;

	png_c->bitmap = NULL;

	png_c->png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
	if (png_c->png == NULL) {
		msg_data.error = messages_get("NoMemory");
		content_broadcast(&png_c->base, CONTENT_MSG_ERROR, msg_data);
		warn_user("NoMemory", 0);
		return NSERROR_NOMEM;
	}

	png_set_error_fn(png_c->png, NULL, nspng_error, nspng_warning);

	png_c->info = png_create_info_struct(png_c->png);
	if (png_c->info == NULL) {
		png_destroy_read_struct(&png_c->png, &png_c->info, 0);

		msg_data.error = messages_get("NoMemory");
		content_broadcast(&png_c->base, CONTENT_MSG_ERROR, msg_data);
		warn_user("NoMemory", 0);
		return NSERROR_NOMEM;
	}

	if (setjmp(png_jmpbuf(png_c->png))) {
		png_destroy_read_struct(&png_c->png, &png_c->info, 0);
		LOG(("Failed to set callbacks"));
		png_c->png = NULL;
		png_c->info = NULL;

		msg_data.error = messages_get("PNGError");
		content_broadcast(&png_c->base, CONTENT_MSG_ERROR, msg_data);
		return NSERROR_NOMEM;
	}

	png_set_progressive_read_fn(png_c->png, png_c,
			info_callback, row_callback, end_callback);

	return NSERROR_OK;
}
Ejemplo n.º 12
0
FXPNG_Context* CCodec_PngModule::Start(void* pModule) {
  FXPNG_Context* p = (FXPNG_Context*)FX_Alloc(uint8_t, sizeof(FXPNG_Context));
  if (!p)
    return nullptr;

  p->m_AllocFunc = _png_alloc_func;
  p->m_FreeFunc = _png_free_func;
  p->png_ptr = nullptr;
  p->info_ptr = nullptr;
  p->parent_ptr = (void*)this;
  p->child_ptr = pModule;
  p->png_ptr =
      png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
  if (!p->png_ptr) {
    FX_Free(p);
    return nullptr;
  }
  p->info_ptr = png_create_info_struct(p->png_ptr);
  if (!p->info_ptr) {
    png_destroy_read_struct(&(p->png_ptr), nullptr, nullptr);
    FX_Free(p);
    return nullptr;
  }
  if (setjmp(png_jmpbuf(p->png_ptr))) {
    if (p) {
      png_destroy_read_struct(&(p->png_ptr), &(p->info_ptr), nullptr);
      FX_Free(p);
    }
    return nullptr;
  }
  png_set_progressive_read_fn(p->png_ptr, p, _png_get_header_func,
                              _png_get_row_func, _png_get_end_func);
  png_set_error_fn(p->png_ptr, m_szLastError, (png_error_ptr)_png_error_data,
                   (png_error_ptr)_png_warning_data);
  return p;
}
Ejemplo n.º 13
0
/* Alternate create PNG structure for reading, and allocate any memory needed. */
png_structp PNGAPI
png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
   png_malloc_ptr malloc_fn, png_free_ptr free_fn)
{
#endif /* PNG_USER_MEM_SUPPORTED */

   png_structp png_ptr;

#ifdef PNG_SETJMP_SUPPORTED
#ifdef USE_FAR_KEYWORD
   jmp_buf jmpbuf;
#endif
#endif

   int i;

   png_debug(1, "in png_create_read_struct\n");
#ifdef PNG_USER_MEM_SUPPORTED
   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
      (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
#else
   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
#endif
   if (png_ptr == NULL)
      return (NULL);

#if !defined(PNG_1_0_X)
#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
   png_init_mmx_flags(png_ptr);   /* 1.2.0 addition */
#endif
#endif /* PNG_1_0_X */

   /* added at libpng-1.2.6 */
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
#endif

#ifdef PNG_SETJMP_SUPPORTED
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
#else
   if (setjmp(png_ptr->jmpbuf))
#endif
   {
      png_free(png_ptr, png_ptr->zbuf);
      png_ptr->zbuf=NULL;
#ifdef PNG_USER_MEM_SUPPORTED
      png_destroy_struct_2((png_voidp)png_ptr,
         (png_free_ptr)free_fn, (png_voidp)mem_ptr);
#else
      png_destroy_struct((png_voidp)png_ptr);
#endif
      return (NULL);
   }
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
#endif
#endif

#ifdef PNG_USER_MEM_SUPPORTED
   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
#endif

   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);

   i=0;
   do
   {
     if(user_png_ver[i] != png_libpng_ver[i])
        png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
   } while (png_libpng_ver[i++]);

   if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
   {
     /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
      * we must recompile any applications that use any older library version.
      * For versions after libpng 1.0, we will be compatible, so we need
      * only check the first digit.
      */
     if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
         (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
         (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
     {
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
        char msg[80];
        if (user_png_ver)
        {
          sprintf(msg, "Application was compiled with png.h from libpng-%.20s",
             user_png_ver);
          png_warning(png_ptr, msg);
        }
        sprintf(msg, "Application  is  running with png.c from libpng-%.20s",
           png_libpng_ver);
        png_warning(png_ptr, msg);
#endif
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
        png_ptr->flags=0;
#endif
        png_error(png_ptr,
           "Incompatible libpng version in application and library");
     }
   }

   /* initialize zbuf - compression buffer */
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
     (png_uint_32)png_ptr->zbuf_size);
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;

   switch (inflateInit(&png_ptr->zstream))
   {
     case Z_OK: /* Do nothing */ break;
     case Z_MEM_ERROR:
     case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
     case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break;
     default: png_error(png_ptr, "Unknown zlib error");
   }

   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;

   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);

#ifdef PNG_SETJMP_SUPPORTED
/* Applications that neglect to set up their own setjmp() and then encounter
   a png_error() will longjmp here.  Since the jmpbuf is then meaningless we
   abort instead of returning. */
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
      PNG_ABORT();
   png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
#else
   if (setjmp(png_ptr->jmpbuf))
      PNG_ABORT();
#endif
#endif
   return (png_ptr);
}
Ejemplo n.º 14
0
bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) {
#ifdef USE_PNG
	destroy();

	// First, check the PNG signature (if not set to skip it)
	if (!_skipSignature) {
		if (stream.readUint32BE() != MKTAG(0x89, 'P', 'N', 'G')) {
			return false;
		}
		if (stream.readUint32BE() != MKTAG(0x0d, 0x0a, 0x1a, 0x0a)) {
			return false;
		}
	}

	// The following is based on the guide provided in:
	//http://www.libpng.org/pub/png/libpng-1.2.5-manual.html#section-3
	//http://www.libpng.org/pub/png/libpng-1.4.0-manual.pdf
	// along with the png-loading code used in the sword25-engine.
	png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (!pngPtr) {
		return false;
	}
	png_infop infoPtr = png_create_info_struct(pngPtr);
	if (!infoPtr) {
		png_destroy_read_struct(&pngPtr, NULL, NULL);
		return false;
	}

	png_set_error_fn(pngPtr, NULL, pngError, pngWarning);
	// TODO: The manual says errors should be handled via setjmp

	png_set_read_fn(pngPtr, &stream, pngReadFromStream);
	png_set_crc_action(pngPtr, PNG_CRC_DEFAULT, PNG_CRC_WARN_USE);
	// We already verified the PNG-header
	png_set_sig_bytes(pngPtr, 8);

	// Read PNG header
	png_read_info(pngPtr, infoPtr);

	// No handling for unknown chunks yet.
	int bitDepth, colorType, width, height, interlaceType;
	png_uint_32 w, h;
	png_get_IHDR(pngPtr, infoPtr, &w, &h, &bitDepth, &colorType, &interlaceType, NULL, NULL);
	width = w;
	height = h;

	// Allocate memory for the final image data.
	// To keep memory framentation low this happens before allocating memory for temporary image data.
	_outputSurface = new Graphics::Surface();

	// Images of all color formats except PNG_COLOR_TYPE_PALETTE
	// will be transformed into ARGB images
	if (colorType == PNG_COLOR_TYPE_PALETTE && !png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS)) {
		int numPalette = 0;
		png_colorp palette = NULL;
		uint32 success = png_get_PLTE(pngPtr, infoPtr, &palette, &numPalette);
		if (success != PNG_INFO_PLTE) {
			png_destroy_read_struct(&pngPtr, &infoPtr, NULL);
			return false;
		}
		_paletteColorCount = numPalette;
		_palette = new byte[_paletteColorCount * 3];
		for (int i = 0; i < _paletteColorCount; i++) {
			_palette[(i * 3)] = palette[i].red;
			_palette[(i * 3) + 1] = palette[i].green;
			_palette[(i * 3) + 2] = palette[i].blue;

		}
		_outputSurface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
		png_set_packing(pngPtr);
	} else {
		bool isAlpha = (colorType & PNG_COLOR_MASK_ALPHA);
		if (png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS)) {
			isAlpha = true;
			png_set_expand(pngPtr);
		}
		_outputSurface->create(width, height, Graphics::PixelFormat(4,
		                       8, 8, 8, isAlpha ? 8 : 0, 24, 16, 8, 0));
		if (!_outputSurface->getPixels()) {
			error("Could not allocate memory for output image.");
		}
		if (bitDepth == 16)
			png_set_strip_16(pngPtr);
		if (bitDepth < 8)
			png_set_expand(pngPtr);
		if (colorType == PNG_COLOR_TYPE_GRAY ||
			colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
			png_set_gray_to_rgb(pngPtr);

		// PNGs are Big-Endian:
#ifdef SCUMM_LITTLE_ENDIAN
		png_set_bgr(pngPtr);
		png_set_swap_alpha(pngPtr);
		if (colorType != PNG_COLOR_TYPE_RGB_ALPHA)
			png_set_filler(pngPtr, 0xff, PNG_FILLER_BEFORE);
#else
		if (colorType != PNG_COLOR_TYPE_RGB_ALPHA)
			png_set_filler(pngPtr, 0xff, PNG_FILLER_AFTER);
#endif

	}

	// After the transformations have been registered, the image data is read again.
	png_set_interlace_handling(pngPtr);
	png_read_update_info(pngPtr, infoPtr);
	png_get_IHDR(pngPtr, infoPtr, &w, &h, &bitDepth, &colorType, NULL, NULL, NULL);
	width = w;
	height = h;

	if (interlaceType == PNG_INTERLACE_NONE) {
		// PNGs without interlacing can simply be read row by row.
		for (int i = 0; i < height; i++) {
			png_read_row(pngPtr, (png_bytep)_outputSurface->getBasePtr(0, i), NULL);
		}
	} else {
		// PNGs with interlacing require us to allocate an auxillary
		// buffer with pointers to all row starts.

		// Allocate row pointer buffer
		png_bytep *rowPtr = new png_bytep[height];
		if (!rowPtr) {
			error("Could not allocate memory for row pointers.");
		}

		// Initialize row pointers
		for (int i = 0; i < height; i++)
			rowPtr[i] = (png_bytep)_outputSurface->getBasePtr(0, i);

		// Read image data
		png_read_image(pngPtr, rowPtr);

		// Free row pointer buffer
		delete[] rowPtr;
	}

	// Read additional data at the end.
	png_read_end(pngPtr, NULL);

	// Destroy libpng structures
	png_destroy_read_struct(&pngPtr, &infoPtr, NULL);

	return true;
#else
	return false;
#endif
}
Ejemplo n.º 15
0
s_screen *pngToScreen(const void *data)
{
    png_structp png_ptr;
    png_infop info_ptr;
    unsigned int sig_read = 0;
    png_uint_32 width, height;
    int bit_depth, color_type, interlace_type, y;
    u32 *line;
    s_screen *image;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if(png_ptr == NULL)
    {
        goto error;
    }
    png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) NULL, png_warning_fn);
    info_ptr = png_create_info_struct(png_ptr);
    if(info_ptr == NULL)
    {
        goto error2;
    }
    if(setjmp(png_jmpbuf(png_ptr)))
    {
        goto error2;
    }

    png_set_read_fn(png_ptr, &data, png_read_fn);
    png_set_sig_bytes(png_ptr, sig_read);
    png_read_info(png_ptr, info_ptr);
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);

    png_set_strip_16(png_ptr);
    png_set_packing(png_ptr);
    if(color_type == PNG_COLOR_TYPE_PALETTE)
    {
        png_set_palette_to_rgb(png_ptr);
    }
    if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    {
        png_set_expand_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 WII
    png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
#else
    png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
#endif

    image = allocscreen(width, height, PIXEL_32);
    if(image == NULL)
    {
        goto error2;
    }

    line = (u32 *)image->data;
    for(y = 0; y < height; y++)
    {
        png_read_row(png_ptr, (u8 *) line, NULL);
        line += width;
    }
    png_read_end(png_ptr, info_ptr);
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    return image;

error2:
    png_destroy_read_struct(&png_ptr, NULL, NULL);
error:
    return NULL;
}
Ejemplo n.º 16
0
/*
 * EncodeBlock
 */
static block_t *EncodeBlock(encoder_t *p_enc, picture_t *p_pic)
{
    encoder_sys_t *p_sys = p_enc->p_sys;

    if( unlikely( !p_pic ) )
    {
        return NULL;
    }

    block_t *p_block = block_Alloc( p_sys->i_blocksize );
    if( p_block == NULL )
    {
        return NULL;
    }

    png_structp p_png = png_create_write_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
    if( p_png == NULL )
    {
        block_Release( p_block );
        return NULL;
    }

    /* save buffer start */
    uint8_t *p_start = p_block->p_buffer;
    size_t i_start = p_block->i_buffer;

    p_sys->b_error = false;
    png_infop p_info = NULL;

    /* libpng longjmp's there in case of error */
    if( setjmp( png_jmpbuf( p_png ) ) )
        goto error;

    png_set_write_fn( p_png, p_block, user_write, user_flush );
    png_set_error_fn( p_png, p_enc, user_error, user_warning );

    p_info = png_create_info_struct( p_png );
    if( p_info == NULL )
        goto error;

    png_infop p_end_info = png_create_info_struct( p_png );
    if( p_end_info == NULL ) goto error;

    const unsigned i_width = p_enc->fmt_in.video.i_visible_width;
    const unsigned i_height = p_enc->fmt_in.video.i_visible_height;

    png_set_IHDR( p_png, p_info,
            i_width,
            i_height,
            8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
            PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT );
    if( p_sys->b_error ) goto error;

    png_write_info( p_png, p_info );
    if( p_sys->b_error ) goto error;

    /* Encode picture */

    for( unsigned i = 0; i < i_height; i++ )
    {
        png_write_row( p_png, p_pic->p->p_pixels + (i_width * i * 3));
        if( p_sys->b_error ) goto error;
    }

    png_write_end( p_png, p_end_info );
    if( p_sys->b_error ) goto error;

    png_destroy_write_struct( &p_png, &p_info );

    /* restore original buffer position */
    p_block->p_buffer = p_start;
    p_block->i_buffer = i_start - p_block->i_buffer;

    p_block->i_dts = p_block->i_pts = p_pic->date;

    return p_block;

 error:

    png_destroy_write_struct( &p_png, p_info ? &p_info : NULL );

    block_Release(p_block);
    return NULL;
}
Ejemplo n.º 17
0
bool writePNG(Common::WriteStream &out, const Graphics::Surface &input, const bool bottomUp) {
#ifdef USE_PNG
	const Graphics::PixelFormat requiredFormat_3byte(3, 8, 8, 8, 0, 16, 8, 0, 0);
	const Graphics::PixelFormat requiredFormat_4byte(4, 8, 8, 8, 8, 0, 8, 16, 24);

	if (input.format.bytesPerPixel == 3) {
		if (input.format != requiredFormat_3byte) {
			warning("Cannot currently write PNG with 3-byte pixel format other than %s", requiredFormat_3byte.toString().c_str());
			return false;
		}
	} else if (input.format.bytesPerPixel != 4) {
		warning("Cannot currently write PNG with pixel format of bpp other than 3, 4");
		return false;
	}

	int colorType;
	Graphics::Surface *tmp = NULL;
	const Graphics::Surface *surface;

	if (input.format == requiredFormat_3byte) {
		surface = &input;
		colorType = PNG_COLOR_TYPE_RGB;
	} else {
		if (input.format == requiredFormat_4byte) {
			surface = &input;
		} else {
			surface = tmp = input.convertTo(requiredFormat_4byte);
		}
		colorType = PNG_COLOR_TYPE_RGB_ALPHA;
	}

	png_structp pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (!pngPtr) {
		return false;
	}
	png_infop infoPtr = png_create_info_struct(pngPtr);
	if (!infoPtr) {
		png_destroy_write_struct(&pngPtr, NULL);
		return false;
	}

	png_set_error_fn(pngPtr, NULL, pngError, pngWarning);
	// TODO: The manual says errors should be handled via setjmp

	png_set_write_fn(pngPtr, &out, pngWriteToStream, pngFlushStream);

	png_set_IHDR(pngPtr, infoPtr, surface->w, surface->h, 8, colorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

	Common::Array<const uint8 *> rows;
	rows.reserve(surface->h);
	if (bottomUp) {
		for (uint y = surface->h; y-- > 0;) {
			rows.push_back((const uint8 *)surface->getBasePtr(0, y));
		}
	} else {
		for (uint y = 0; y < surface->h; ++y) {
			rows.push_back((const uint8 *)surface->getBasePtr(0, y));
		}
	}

	png_set_rows(pngPtr, infoPtr, const_cast<uint8 **>(&rows.front()));
	png_write_png(pngPtr, infoPtr, 0, NULL);
	png_destroy_write_struct(&pngPtr, &infoPtr);

	// free tmp surface
	if (tmp) {
		tmp->free();
		delete tmp;
	}

	return true;
#else
	return false;
#endif
}
bool PNGImageFileType::read(      Image        *OSG_PNG_ARG(pImage  ), 
                                  std::istream &OSG_PNG_ARG(is      ),
                            const std::string  &OSG_PNG_ARG(mimetype))
{
#ifdef OSG_WITH_PNG

    bool                retCode;
    Image::PixelFormat  pixelFormat = OSG::Image::OSG_INVALID_PF;
    png_structp         png_ptr;
    png_infop           info_ptr;
    png_uint_32         width, wc, height, h, i, res_x, res_y;
    png_byte            bit_depth, channels, color_type;
    png_bytep           *row_pointers, base;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);

    if(!png_ptr)
        return false;

    png_set_error_fn(png_ptr, 0, &errorOutput, &warningOutput);

    info_ptr = png_create_info_struct(png_ptr);

    if(!info_ptr)
    {
        png_destroy_read_struct(&png_ptr, 0, 0);
        return false;
    }

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

    png_set_read_fn(png_ptr, &is, &isReadFunc);

    png_read_info(png_ptr, info_ptr);

    width = png_get_image_width(png_ptr, info_ptr);
    height = png_get_image_height(png_ptr, info_ptr);
    bit_depth = png_get_bit_depth(png_ptr, info_ptr);
    res_x = png_get_x_pixels_per_meter(png_ptr, info_ptr);
    res_y = png_get_y_pixels_per_meter(png_ptr, info_ptr);
    channels = png_get_channels(png_ptr, info_ptr);
    color_type = png_get_color_type(png_ptr, info_ptr);

    // Convert paletted images to RGB
    if (color_type == PNG_COLOR_TYPE_PALETTE)
    {
        png_set_palette_to_rgb(png_ptr);
        channels = 3;
        bit_depth = 8;
    }

    // Convert < 8 bit to 8 bit
    if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    {
        png_set_gray_1_2_4_to_8(png_ptr);
        bit_depth = 8;
    }

#if BYTE_ORDER == LITTLE_ENDIAN
    if (bit_depth == 16)
        png_set_swap(png_ptr);
#endif

    // Add a full alpha channel if there is transparency
    // information in a tRNS chunk
    if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    {
        png_set_tRNS_to_alpha(png_ptr);
        ++channels;
    } 

    Int32 dataType;

    switch (bit_depth) 
    {
        case 8:
            dataType = Image::OSG_UINT8_IMAGEDATA;
            break;
        case 16:
            dataType = Image::OSG_UINT16_IMAGEDATA;
            break;
        default:
            FWARNING (( "Invalid bit_depth: %d, can not read png-data\n",
                        bit_depth ));
            return false;
    }

    switch(channels)
    {
        case 1:
            pixelFormat = Image::OSG_L_PF;
            break;
        case 2:
            pixelFormat = Image::OSG_LA_PF;
            break;
        case 3:
            pixelFormat = Image::OSG_RGB_PF;
            break;
        case 4:
            pixelFormat = Image::OSG_RGBA_PF;
        break;
    };
    
    if(pImage->set(pixelFormat, width, height,
                   1, 1, 1, 0.0, 0,
                   dataType))
    {
        // set resolution png supports only pixel per meter,
        // so we do a conversion to dpi with some rounding.
        res_x = png_uint_32((Real32(res_x) / 39.37007874f) < 0.0f ?
                            (Real32(res_x) / 39.37007874f) - 0.5f :
                            (Real32(res_x) / 39.37007874f) + 0.5f);
        res_y = png_uint_32((Real32(res_y) / 39.37007874f) < 0.0f ?
                            (Real32(res_y) / 39.37007874f) - 0.5f :
                            (Real32(res_y) / 39.37007874f) + 0.5f);

        pImage->setResX(Real32(res_x));
        pImage->setResY(Real32(res_y));
        pImage->setResUnit(Image::OSG_RESUNIT_INCH);

        // Calculate the row pointers
        row_pointers = new png_bytep[height];
        wc = width * channels * (bit_depth / 8);
        h = height - 1;
        base = pImage->editData();

        for(i = 0; i < height; ++i)
            row_pointers[i] = base + (h - i) * wc;

        // Read the image data
        png_read_image(png_ptr, row_pointers);

        delete[] row_pointers;

        retCode = true;
    }
    else
    {
        retCode = false;
    }

    png_destroy_read_struct(&png_ptr, &info_ptr, 0);

    return retCode;

#else

    SWARNING << getMimeType() 
             << " read is not compiled into the current binary " 
             << std::endl;

    return false;

#endif

}
Ejemplo n.º 19
0
/****************************************************************************
 * DecodeBlock: the whole thing
 ****************************************************************************
 * This function must be fed with a complete compressed frame.
 ****************************************************************************/
static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_block;
    picture_t *p_pic = 0;

    png_uint_32 i_width, i_height;
    int i_color_type, i_interlace_type, i_compression_type, i_filter_type;
    int i_bit_depth, i;

    png_structp p_png;
    png_infop p_info, p_end_info;
    png_bytep *p_row_pointers = NULL;

    if( !pp_block || !*pp_block ) return NULL;

    p_block = *pp_block;
    p_sys->b_error = false;

    if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
    {
        block_Release( p_block ); *pp_block = NULL;
        return NULL;
    }

    p_png = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
    if( p_png == NULL )
    {
        block_Release( p_block ); *pp_block = NULL;
        return NULL;
    }

    p_info = png_create_info_struct( p_png );
    if( p_info == NULL )
    {
        png_destroy_read_struct( &p_png, NULL, NULL );
        block_Release( p_block ); *pp_block = NULL;
        return NULL;
    }

    p_end_info = png_create_info_struct( p_png );
    if( p_end_info == NULL )
    {
        png_destroy_read_struct( &p_png, &p_info, NULL );
        block_Release( p_block ); *pp_block = NULL;
        return NULL;
    }

    /* libpng longjmp's there in case of error */
    if( setjmp( png_jmpbuf( p_png ) ) )
        goto error;

    png_set_read_fn( p_png, (void *)p_block, user_read );
    png_set_error_fn( p_png, (void *)p_dec, user_error, user_warning );

    png_read_info( p_png, p_info );
    if( p_sys->b_error ) goto error;

    png_get_IHDR( p_png, p_info, &i_width, &i_height,
                  &i_bit_depth, &i_color_type, &i_interlace_type,
                  &i_compression_type, &i_filter_type);
    if( p_sys->b_error ) goto error;

    /* Set output properties */
    p_dec->fmt_out.i_codec = VLC_CODEC_RGBA;
    p_dec->fmt_out.video.i_visible_width = p_dec->fmt_out.video.i_width = i_width;
    p_dec->fmt_out.video.i_visible_height = p_dec->fmt_out.video.i_height = i_height;
    p_dec->fmt_out.video.i_sar_num = 1;
    p_dec->fmt_out.video.i_sar_den = 1;
    p_dec->fmt_out.video.i_rmask = 0x000000ff;
    p_dec->fmt_out.video.i_gmask = 0x0000ff00;
    p_dec->fmt_out.video.i_bmask = 0x00ff0000;

    if( i_color_type == PNG_COLOR_TYPE_PALETTE )
        png_set_palette_to_rgb( p_png );

    if( i_color_type == PNG_COLOR_TYPE_GRAY ||
        i_color_type == PNG_COLOR_TYPE_GRAY_ALPHA )
          png_set_gray_to_rgb( p_png );

    /* Strip to 8 bits per channel */
    if( i_bit_depth == 16 ) png_set_strip_16( p_png );

    if( png_get_valid( p_png, p_info, PNG_INFO_tRNS ) )
    {
        png_set_tRNS_to_alpha( p_png );
    }
    else if( !(i_color_type & PNG_COLOR_MASK_ALPHA) )
    {
        p_dec->fmt_out.i_codec = VLC_CODEC_RGB24;
    }

    /* Get a new picture */
    p_pic = decoder_NewPicture( p_dec );
    if( !p_pic ) goto error;

    /* Decode picture */
    p_row_pointers = malloc( sizeof(png_bytep) * i_height );
    if( !p_row_pointers )
        goto error;
    for( i = 0; i < (int)i_height; i++ )
        p_row_pointers[i] = p_pic->p->p_pixels + p_pic->p->i_pitch * i;

    png_read_image( p_png, p_row_pointers );
    if( p_sys->b_error ) goto error;
    png_read_end( p_png, p_end_info );
    if( p_sys->b_error ) goto error;

    png_destroy_read_struct( &p_png, &p_info, &p_end_info );
    free( p_row_pointers );

    p_pic->date = p_block->i_pts > VLC_TS_INVALID ? p_block->i_pts : p_block->i_dts;

    block_Release( p_block ); *pp_block = NULL;
    return p_pic;

 error:

    free( p_row_pointers );
    png_destroy_read_struct( &p_png, &p_info, &p_end_info );
    block_Release( p_block ); *pp_block = NULL;
    return NULL;
}
Ejemplo n.º 20
0
static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_filerw *file, rt_bool_t load)
{
    png_uint_32 width;
    png_uint_32 height;
    int bit_depth;
    int color_type;
    double gamma;
    struct rtgui_image_png *png;

    png = (struct rtgui_image_png *) rtgui_malloc(sizeof(struct rtgui_image_png));
    png->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (png->png_ptr == RT_NULL)
    {
        rtgui_free(png);
        return RT_FALSE;
    }
	png_set_error_fn(png->png_ptr, RT_NULL, _image_png_error_fn, _image_png_error_fn);
	
    png->info_ptr = png_create_info_struct(png->png_ptr);
    if (png->info_ptr == RT_NULL)
    {
        png_destroy_read_struct(&png->png_ptr, NULL, NULL);
        rtgui_free(png);
        return RT_FALSE;
    }

    png->filerw = file;
	png->is_loaded = RT_FALSE;
    png_set_read_fn(png->png_ptr, png->filerw, rtgui_image_png_read_data);

    png_read_info(png->png_ptr, png->info_ptr);
    png_get_IHDR(png->png_ptr, png->info_ptr, &width, &height, &bit_depth,
                 &color_type, NULL, NULL, NULL);

    /* set image information */
    image->w = width;
    image->h = height;
    image->engine = &rtgui_image_png_engine;
    image->data = png;

    if (bit_depth == 16)
        png_set_strip_16(png->png_ptr);
    if (color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_expand(png->png_ptr);
    if (bit_depth < 8)
        png_set_expand(png->png_ptr);
    if (png_get_valid(png->png_ptr, png->info_ptr, PNG_INFO_tRNS))
        png_set_expand(png->png_ptr);
    if (color_type == PNG_COLOR_TYPE_GRAY ||
            color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png->png_ptr);

    /* Ignore background color */

    /* set gamma conversion */
    if (png_get_gAMA(png->png_ptr, png->info_ptr, &gamma))
        png_set_gamma(png->png_ptr, (double)2.2, gamma);

    png_read_update_info(png->png_ptr, png->info_ptr);

    if (load == RT_TRUE)
    {
        /* load all pixels */
        png->pixels = rtgui_malloc(image->w * image->h * sizeof(rtgui_color_t));
        if (png->pixels == RT_NULL)
        {
            png_read_end(png->png_ptr, RT_NULL);

            /* destroy png struct */
            png_destroy_info_struct(png->png_ptr, &png->info_ptr);
            png_destroy_read_struct(&png->png_ptr, RT_NULL, RT_NULL);

            /* release data */
            rtgui_free(png);
            return RT_FALSE;
        }

        rtgui_image_png_process(png->png_ptr, png->info_ptr, png);
		png_read_end(png->png_ptr, RT_NULL);
		png->is_loaded = RT_TRUE;
		/* close file handler */
		rtgui_filerw_close(png->filerw);
		png->filerw = RT_NULL;
    }
    else
    {
        png->pixels = RT_NULL;
    }

    return RT_TRUE;
}
Ejemplo n.º 21
0
/* Test one file */
int
test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
{
   static png_FILE_p fpin;
   static png_FILE_p fpout;  /* "static" prevents setjmp corruption */
   png_structp read_ptr;
   png_infop read_info_ptr, end_info_ptr;
#ifdef PNG_WRITE_SUPPORTED
   png_structp write_ptr;
   png_infop write_info_ptr;
   png_infop write_end_info_ptr;
#else
   png_structp write_ptr = NULL;
   png_infop write_info_ptr = NULL;
   png_infop write_end_info_ptr = NULL;
#endif
   png_bytep row_buf;
   png_uint_32 y;
   png_uint_32 width, height;
   int num_pass, pass;
   int bit_depth, color_type;
#ifdef PNG_SETJMP_SUPPORTED
#ifdef USE_FAR_KEYWORD
   jmp_buf jmpbuf;
#endif
#endif

#if defined(_WIN32_WCE)
   TCHAR path[MAX_PATH];
#endif
   char inbuf[256], outbuf[256];

   row_buf = NULL;

#if defined(_WIN32_WCE)
   MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH);
   if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
#else
   if ((fpin = fopen(inname, "rb")) == NULL)
#endif
   {
      fprintf(STDERR, "Could not find input file %s\n", inname);
      return (1);
   }

#if defined(_WIN32_WCE)
   MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH);
   if ((fpout = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE)
#else
   if ((fpout = fopen(outname, "wb")) == NULL)
#endif
   {
      fprintf(STDERR, "Could not open output file %s\n", outname);
      FCLOSE(fpin);
      return (1);
   }

   png_debug(0, "Allocating read and write structures\n");
#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
   read_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
      png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
      (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
#else
   read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
      png_error_ptr_NULL, png_error_ptr_NULL);
#endif
#if defined(PNG_NO_STDIO)
   png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error,
       pngtest_warning);
#endif
#ifdef PNG_WRITE_SUPPORTED
#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
   write_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
      png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
      (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
#else
   write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
      png_error_ptr_NULL, png_error_ptr_NULL);
#endif
#if defined(PNG_NO_STDIO)
   png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error,
       pngtest_warning);
#endif
#endif
   png_debug(0, "Allocating read_info, write_info and end_info structures\n");
   read_info_ptr = png_create_info_struct(read_ptr);
   end_info_ptr = png_create_info_struct(read_ptr);
#ifdef PNG_WRITE_SUPPORTED
   write_info_ptr = png_create_info_struct(write_ptr);
   write_end_info_ptr = png_create_info_struct(write_ptr);
#endif

#ifdef PNG_SETJMP_SUPPORTED
   png_debug(0, "Setting jmpbuf for read struct\n");
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
#else
   if (setjmp(png_jmpbuf(read_ptr)))
#endif
   {
      fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
      if (row_buf)
         png_free(read_ptr, row_buf);
      png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
#ifdef PNG_WRITE_SUPPORTED
      png_destroy_info_struct(write_ptr, &write_end_info_ptr);
      png_destroy_write_struct(&write_ptr, &write_info_ptr);
#endif
      FCLOSE(fpin);
      FCLOSE(fpout);
      return (1);
   }
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_jmpbuf(read_ptr),jmpbuf,png_sizeof(jmp_buf));
#endif

#ifdef PNG_WRITE_SUPPORTED
   png_debug(0, "Setting jmpbuf for write struct\n");
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
#else
   if (setjmp(png_jmpbuf(write_ptr)))
#endif
   {
      fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
      png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
      png_destroy_info_struct(write_ptr, &write_end_info_ptr);
#ifdef PNG_WRITE_SUPPORTED
      png_destroy_write_struct(&write_ptr, &write_info_ptr);
#endif
      FCLOSE(fpin);
      FCLOSE(fpout);
      return (1);
   }
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_jmpbuf(write_ptr),jmpbuf,png_sizeof(jmp_buf));
#endif
#endif
#endif

   png_debug(0, "Initializing input and output streams\n");
#if !defined(PNG_NO_STDIO)
   png_init_io(read_ptr, fpin);
#  ifdef PNG_WRITE_SUPPORTED
   png_init_io(write_ptr, fpout);
#  endif
#else
   png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);
#  ifdef PNG_WRITE_SUPPORTED
   png_set_write_fn(write_ptr, (png_voidp)fpout,  pngtest_write_data,
#    if defined(PNG_WRITE_FLUSH_SUPPORTED)
      pngtest_flush);
#    else
      NULL);
#    endif
#  endif
#endif
   if(status_dots_requested == 1)
   {
#ifdef PNG_WRITE_SUPPORTED
      png_set_write_status_fn(write_ptr, write_row_callback);
#endif
      png_set_read_status_fn(read_ptr, read_row_callback);
   }
   else
   {
#ifdef PNG_WRITE_SUPPORTED
      png_set_write_status_fn(write_ptr, png_write_status_ptr_NULL);
#endif
      png_set_read_status_fn(read_ptr, png_read_status_ptr_NULL);
   }

#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
   {
     int i;
     for(i=0; i<256; i++)
        filters_used[i]=0;
     png_set_read_user_transform_fn(read_ptr, count_filters);
   }
#endif
#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
   zero_samples=0;
   png_set_write_user_transform_fn(write_ptr, count_zero_samples);
#endif

#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
#  ifndef PNG_HANDLE_CHUNK_ALWAYS
#    define PNG_HANDLE_CHUNK_ALWAYS       3
#  endif
   png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
      png_bytep_NULL, 0);
#endif
#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
#  ifndef PNG_HANDLE_CHUNK_IF_SAFE
#    define PNG_HANDLE_CHUNK_IF_SAFE      2
#  endif
   png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE,
      png_bytep_NULL, 0);
#endif

   png_debug(0, "Reading info struct\n");
   png_read_info(read_ptr, read_info_ptr);

   png_debug(0, "Transferring info struct\n");
   {
      int interlace_type, compression_type, filter_type;

      if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
          &color_type, &interlace_type, &compression_type, &filter_type))
      {
         png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
            color_type, interlace_type, compression_type, filter_type);
#else
            color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
#endif
      }
   }
Ejemplo n.º 22
0
static
void read_png_image(QImageIO* iio)
{
    png_structp png_ptr;
    png_infop info_ptr;
    png_infop end_info;
    png_bytep* row_pointers;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);
    if (!png_ptr) {
	iio->setStatus(-1);
	return;
    }

    png_set_error_fn(png_ptr, 0, 0, qt_png_warning);

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
	png_destroy_read_struct(&png_ptr, 0, 0);
	iio->setStatus(-2);
	return;
    }

    end_info = png_create_info_struct(png_ptr);
    if (!end_info) {
	png_destroy_read_struct(&png_ptr, &info_ptr, 0);
	iio->setStatus(-3);
	return;
    }

    if (setjmp(png_ptr->jmpbuf)) {
	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
	iio->setStatus(-4);
	return;
    }

    png_set_read_fn(png_ptr, (void*)iio, iod_read_fn);
    png_read_info(png_ptr, info_ptr);

    QImage image;
    setup_qt(image, png_ptr, info_ptr, iio->gamma());
    if (image.isNull()) {
	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
	iio->setStatus(-5);
	return;
    }

    png_uint_32 width;
    png_uint_32 height;
    int bit_depth;
    int color_type;
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
	0, 0, 0);

    uchar** jt = image.jumpTable();
    row_pointers=new png_bytep[height];

    for (uint y=0; y<height; y++) {
	row_pointers[y]=jt[y];
    }

    png_read_image(png_ptr, row_pointers);

#if 0 // libpng takes care of this.
png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)
    if (image.depth()==32 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
	QRgb trans = 0xFF000000 | qRgb(
	      (info_ptr->trans_values.red << 8 >> bit_depth)&0xff,
	      (info_ptr->trans_values.green << 8 >> bit_depth)&0xff,
	      (info_ptr->trans_values.blue << 8 >> bit_depth)&0xff);
	for (uint y=0; y<height; y++) {
	    for (uint x=0; x<info_ptr->width; x++) {
		if (((uint**)jt)[y][x] == trans) {
		    ((uint**)jt)[y][x] &= 0x00FFFFFF;
		} else {
		}
	    }
	}
    }
Ejemplo n.º 23
0
int ReadPNG(FILE* in_file, WebPPicture* const pic, int keep_alpha,
            Metadata* const metadata) {
  png_structp png;
  png_infop info = NULL;
  png_infop end_info = NULL;
  int color_type, bit_depth, interlaced;
  int has_alpha;
  int num_passes;
  int p;
  int ok = 0;
  png_uint_32 width, height, y;
  int stride;
  uint8_t* rgb = NULL;

  png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
  if (png == NULL) {
    goto End;
  }

  png_set_error_fn(png, 0, error_function, NULL);
  if (setjmp(png_jmpbuf(png))) {
 Error:
    MetadataFree(metadata);
    png_destroy_read_struct(&png, &info, &end_info);
    goto End;
  }

  info = png_create_info_struct(png);
  if (info == NULL) goto Error;
  end_info = png_create_info_struct(png);
  if (end_info == NULL) goto Error;

  png_init_io(png, in_file);
  png_read_info(png, info);
  if (!png_get_IHDR(png, info,
                    &width, &height, &bit_depth, &color_type, &interlaced,
                    NULL, NULL)) goto Error;

  png_set_strip_16(png);
  png_set_packing(png);
  if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
  if (color_type == PNG_COLOR_TYPE_GRAY ||
      color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
    if (bit_depth < 8) {
      png_set_expand_gray_1_2_4_to_8(png);
    }
    png_set_gray_to_rgb(png);
  }
  if (png_get_valid(png, info, PNG_INFO_tRNS)) {
    png_set_tRNS_to_alpha(png);
    has_alpha = 1;
  } else {
    has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA);
  }

  if (!keep_alpha) {
    png_set_strip_alpha(png);
    has_alpha = 0;
  }

  num_passes = png_set_interlace_handling(png);
  png_read_update_info(png, info);
  stride = (has_alpha ? 4 : 3) * width * sizeof(*rgb);
  rgb = (uint8_t*)malloc(stride * height);
  if (rgb == NULL) goto Error;
  for (p = 0; p < num_passes; ++p) {
    for (y = 0; y < height; ++y) {
      png_bytep row = rgb + y * stride;
      png_read_rows(png, &row, NULL, 1);
    }
  }
  png_read_end(png, end_info);

  if (metadata != NULL &&
      !ExtractMetadataFromPNG(png, info, end_info, metadata)) {
    fprintf(stderr, "Error extracting PNG metadata!\n");
    goto Error;
  }

  png_destroy_read_struct(&png, &info, &end_info);

  pic->width = width;
  pic->height = height;
  ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, stride)
                 : WebPPictureImportRGB(pic, rgb, stride);

  if (!ok) {
    goto Error;
  }

 End:
  free(rgb);
  return ok;
}
Ejemplo n.º 24
0
gboolean read_png(curlMemoryStructGCS *chunk, unsigned char **raw_image, picSrcImageInfoGCS *info, char *errBuf) 
{
		
  png_structp png_ptr;
  png_infop info_ptr;
  /* initialize stuff */
  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

  if (!png_ptr) {
    GST_DEBUG("png_create_read_struct failed");
    strcpy(errBuf, "read_png - Error : png_create_read_struct failed");
    return FALSE;
  }
  info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    GST_DEBUG("png_create_info_struct failed"); 
    strcpy(errBuf, "read_png - Error : png_create_info_struct failed");
    return FALSE; 
  }
  FILE* memstream = fmemopen((void *)chunk->memory, chunk->size, "rb");
  if (!memstream) {
    GST_DEBUG("fmemopen failed"); 
    strcpy(errBuf, "read_imgheader - Error : fmemopen failed");
    return FALSE; 
  }		  
  png_init_io(png_ptr, memstream);
		  
  png_set_error_fn(png_ptr, (png_voidp)NULL,  png_error_fn, png_warning_fn);

		 
  /* read file */
  if (setjmp(png_jmpbuf(png_ptr))) {
    sprintf(errBuf, "read_png - Error : %s", "undetermined"); 
    fclose(memstream);
    return FALSE;
  }
		  
       
  png_uint_32 imgWidth, imgHeight;
  int bitdepth, color_type;
		 
  png_read_info(png_ptr, info_ptr);
  png_get_IHDR( png_ptr, info_ptr, &imgWidth, &imgHeight,
                &bitdepth, &color_type, 0, 0, 0 );		  
  //Number of channels
  int channels   = png_get_channels(png_ptr, info_ptr);
		 
  switch (color_type) {
  case PNG_COLOR_TYPE_PALETTE:
    png_set_palette_to_rgb(png_ptr);
    channels = 3;
    info->colorspace =  COLOR_TYPE_GCS_RGB;          
    break;
  case PNG_COLOR_TYPE_GRAY:
    if (bitdepth < 8)
      png_set_gray_1_2_4_to_8(png_ptr);
    //And the bitdepth info
    bitdepth = 8;
    png_set_gray_to_rgb(png_ptr);
    info->colorspace =  COLOR_TYPE_GCS_RGB;       
    break;
  }
  /*if the image has a transperancy set.. convert it to a full Alpha channel..*/
  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
    png_set_tRNS_to_alpha(png_ptr);
    channels+=1;
    info->colorspace =  COLOR_TYPE_GCS_RGB_ALPHA;   
  }
  //We don't support 16 bit precision.. so if the image Has 16 bits per channel
  //precision... round it down to 8.
  if (bitdepth == 16)
    png_set_strip_16(png_ptr);
		  
  info->width	 = imgWidth;
  info->height   = imgHeight;
  info->channels = channels;
		   	
		  
  /* read file */
  if (setjmp(png_jmpbuf(png_ptr))) {
    sprintf(errBuf, "read_png - Error : %s", "undetermined");
    fclose(memstream);
    return FALSE;
  }
		  
		   
  png_bytep* rowPtrs[imgHeight];
         
			
         
			
  *raw_image = (unsigned char*)malloc(imgWidth * imgHeight * bitdepth * channels / 8);
  const unsigned int stride = imgWidth * bitdepth * channels / 8;
  GST_DEBUG("imgWidth:%d, imgHeight:%d, bitdepth:%d, channels:%d, stride:%d", imgWidth,imgHeight,bitdepth,channels, stride  );
  size_t i;
  for (i = 0; i < imgHeight; i++) {         	
    rowPtrs[i] = (png_bytep*)((png_bytep)(*raw_image) + ( i  * stride));

  }
  png_read_image(png_ptr, (png_bytepp)rowPtrs);
  fclose(memstream);
  return TRUE;
}
Ejemplo n.º 25
0
ImageContext* PNGImageLoader::loadHeader(PixelFormat& formatSource, DataSource* data)
{
    PNGImageContext* png = new PNGImageContext(data);
    if (!png)
    {    
        return 0;
        
    }
    // Prepare png loading 
    png->d_png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
    if (png->d_png_ptr == 0)
    {
        delete png;
        return 0;
    }
    png->d_info_ptr = png_create_info_struct(png->d_png_ptr);
    if (png->d_info_ptr == 0)
    {
        delete png;
        return 0;
    }
    if (setjmp(png_jmpbuf(png->d_png_ptr))) 
    {
        delete png;
        return 0;
    }
    png_set_error_fn(png->d_png_ptr, 0, PNG_error_function, PNG_warning_function);
    png_set_read_fn(png->d_png_ptr, png, PNG_read_function);
    //png_set_sig_bytes(png->d_png_ptr, 8);
    


    // Read header Check whether PNG can depaletize transparently or not
    int png_transform = PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_EXPAND;
    //printf("Start reading png\n");
    png_read_png(png->d_png_ptr, png->d_info_ptr, png_transform, 0);
    png->setImageSize();
    png->d_bit_depth = png_get_bit_depth(png->d_png_ptr, png->d_info_ptr);
    png->d_num_channels = png_get_channels(png->d_png_ptr, png->d_info_ptr);
    //printf("PNG Info: width: %d height: %d bpp: %d channels: %d\n", png->getWidth(), png->getHeight(), png->d_bit_depth, png->d_num_channels);
    if (png->d_bit_depth == 8)
    {
        if (png->d_num_channels == 4)
        {    
            formatSource = PF_RGBA;
        }
        else if (png->d_num_channels == 3)
        {   
            formatSource = PF_RGB;
        }
        else 
        {
            delete png;
            return 0;
        }
    }
    // Paletized or grayscale not yet handled 
    else 
    {
        delete png;
        return 0;
    }
    return png;
}
UInt64 PNGImageFileType::restoreData(      Image  *OSG_PNG_ARG  (pImage ),
                                     const UChar8 *OSG_PNG_ARG  (buffer ),
                                           Int32   OSG_CHECK_ARG(memSize))
{
#ifdef OSG_WITH_PNG

    UInt64              retCode;
    Image::PixelFormat  pixelFormat = Image::OSG_INVALID_PF;
    png_structp         png_ptr;
    png_infop           info_ptr;
    png_uint_32         width, wc, height, h, i;
    png_byte            bit_depth, channels, color_type;
    png_bytep           *row_pointers, base;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);

    if(!png_ptr)
    {
        return 0;
    }

    png_set_error_fn(png_ptr, 0, &errorOutput, &warningOutput);

    info_ptr = png_create_info_struct(png_ptr);

    if(!info_ptr)
    {
        png_destroy_read_struct(&png_ptr, 0, 0);
        return 0;
    }

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

    BufferInfo bufferInfo;
    bufferInfo.buffer = const_cast<UChar8 *>(buffer);
    bufferInfo.length = 0;
    png_set_read_fn(png_ptr, static_cast<void *>(&bufferInfo), user_read_data);

    png_read_info(png_ptr, info_ptr);

    width = png_get_image_width(png_ptr, info_ptr);
    height = png_get_image_height(png_ptr, info_ptr);
    bit_depth = png_get_bit_depth(png_ptr, info_ptr);
    channels = png_get_channels(png_ptr, info_ptr);
    color_type = png_get_color_type(png_ptr, info_ptr);

    // Convert paletted images to RGB
    if(color_type == PNG_COLOR_TYPE_PALETTE)
    {
        png_set_palette_to_rgb(png_ptr);
        channels = 3;
        bit_depth = 8;
    }

    // Convert < 8 bit to 8 bit
    if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    {
        png_set_gray_1_2_4_to_8(png_ptr);
        bit_depth = 8;
    }

#if BYTE_ORDER == LITTLE_ENDIAN
    if (bit_depth == 16)
        png_set_swap(png_ptr);
#endif
   
    // Add a full alpha channel if there is transparency
    // information in a tRNS chunk
    if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    {
        png_set_tRNS_to_alpha(png_ptr);
        ++channels;
    }   
                                                                 
    Int32 dataType;

    switch (bit_depth) 
    {
        case 8:
            dataType = Image::OSG_UINT8_IMAGEDATA;
            break;
        case 16:
            dataType = Image::OSG_UINT16_IMAGEDATA;
            break;
        default:
            FWARNING (( "Invalid bit_depth: %d, can not read png-data\n",
                        bit_depth ));
            return false;
    }
    
    switch(channels)
    {
        case 1:
            pixelFormat = Image::OSG_L_PF;
            break;
        case 2:
            pixelFormat = Image::OSG_LA_PF;
            break;
        case 3:
            pixelFormat = Image::OSG_RGB_PF;
            break;
        case 4:
            pixelFormat = Image::OSG_RGBA_PF;
            break;
    };
    
    if(pImage->set(pixelFormat, width, height,
                   1, 1, 1, 0.0, 0,
                   dataType))
    {
        // Calculate the row pointers
        row_pointers = new png_bytep[height];
        wc = width * channels * (bit_depth / 8);
        h = height - 1;
        base = pImage->editData();

        for(i = 0; i < height; ++i)
            row_pointers[i] = base + (h - i) * wc;

        // Read the image data
        png_read_image(png_ptr, row_pointers);
        
        delete[] row_pointers;
        
        retCode = bufferInfo.length;
    }
    else
    {
        retCode = 0;
    }

    png_destroy_read_struct(&png_ptr, &info_ptr, 0);
    
    return retCode;

#else
    SWARNING << getMimeType() 
             << " restoreData is not compiled into the current binary " 
             << std::endl;

    return 0;
#endif
}
Ejemplo n.º 27
0
int ReadPNG(const uint8_t* const data, size_t data_size,
            struct WebPPicture* const pic,
            int keep_alpha, struct Metadata* const metadata) {
  volatile png_structp png = NULL;
  volatile png_infop info = NULL;
  volatile png_infop end_info = NULL;
  PNGReadContext context = { NULL, 0, 0 };
  int color_type, bit_depth, interlaced;
  int has_alpha;
  int num_passes;
  int p;
  volatile int ok = 0;
  png_uint_32 width, height, y;
  int64_t stride;
  uint8_t* volatile rgb = NULL;

  if (data == NULL || data_size == 0 || pic == NULL) return 0;

  context.data = data;
  context.data_size = data_size;

  png = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL,
                                 NULL, MallocFunc, FreeFunc);
  if (png == NULL) goto End;

  png_set_error_fn(png, 0, error_function, NULL);
  if (setjmp(png_jmpbuf(png))) {
 Error:
    MetadataFree(metadata);
    goto End;
  }

  info = png_create_info_struct(png);
  if (info == NULL) goto Error;
  end_info = png_create_info_struct(png);
  if (end_info == NULL) goto Error;

  png_set_read_fn(png, &context, ReadFunc);
  png_read_info(png, info);
  if (!png_get_IHDR(png, info,
                    &width, &height, &bit_depth, &color_type, &interlaced,
                    NULL, NULL)) goto Error;

  png_set_strip_16(png);
  png_set_packing(png);
  if (color_type == PNG_COLOR_TYPE_PALETTE) {
    png_set_palette_to_rgb(png);
  }
  if (color_type == PNG_COLOR_TYPE_GRAY ||
      color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
    if (bit_depth < 8) {
      png_set_expand_gray_1_2_4_to_8(png);
    }
    png_set_gray_to_rgb(png);
  }
  if (png_get_valid(png, info, PNG_INFO_tRNS)) {
    png_set_tRNS_to_alpha(png);
    has_alpha = 1;
  } else {
    has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA);
  }

  // Apply gamma correction if needed.
  {
    double image_gamma = 1 / 2.2, screen_gamma = 2.2;
    int srgb_intent;
    if (png_get_sRGB(png, info, &srgb_intent) ||
        png_get_gAMA(png, info, &image_gamma)) {
      png_set_gamma(png, screen_gamma, image_gamma);
    }
  }

  if (!keep_alpha) {
    png_set_strip_alpha(png);
    has_alpha = 0;
  }

  num_passes = png_set_interlace_handling(png);
  png_read_update_info(png, info);

  stride = (int64_t)(has_alpha ? 4 : 3) * width * sizeof(*rgb);
  if (stride != (int)stride ||
      !ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) {
    goto Error;
  }

  rgb = (uint8_t*)malloc((size_t)stride * height);
  if (rgb == NULL) goto Error;
  for (p = 0; p < num_passes; ++p) {
    png_bytep row = rgb;
    for (y = 0; y < height; ++y) {
      png_read_rows(png, &row, NULL, 1);
      row += stride;
    }
  }
  png_read_end(png, end_info);

  if (metadata != NULL &&
      !ExtractMetadataFromPNG(png, info, end_info, metadata)) {
    fprintf(stderr, "Error extracting PNG metadata!\n");
    goto Error;
  }

  pic->width = (int)width;
  pic->height = (int)height;
  ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, (int)stride)
                 : WebPPictureImportRGB(pic, rgb, (int)stride);

  if (!ok) {
    goto Error;
  }

 End:
  if (png != NULL) {
    png_destroy_read_struct((png_structpp)&png,
                            (png_infopp)&info, (png_infopp)&end_info);
  }
  free(rgb);
  return ok;
}
Ejemplo n.º 28
0
 int read_png(const std::string & file_name, image_t & image) {
  png_structp png;
  png_infop info;
  int color_type, bit_depth, interlaced;
  int has_alpha;
  int num_passes;
  int p;
  int ok = 0;
  png_uint_32 width, height, y;
  int stride;
  uint8_t* rgb = NULL;

  FILE * fp;

	#ifdef LINUX
	  fp = fopen(file_name.c_str(), "rb");
	#endif
	#ifdef WINDOWS
	  fopen_s(&fp, file_name.c_str(), "rb");
	#endif
	if (fp == NULL)
		throw  webp::exception::FileOperationException();

  png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
  if (png == NULL) {
    goto End;
  }

  png_set_error_fn(png, 0, error_function, NULL);
  if (setjmp(png_jmpbuf(png))) {
 Error:
    png_destroy_read_struct(&png, NULL, NULL);
    free(rgb);
    goto End;
  }

  info = png_create_info_struct(png);
  if (info == NULL) goto Error;

  png_init_io(png, fp);
  png_read_info(png, info);
  if (!png_get_IHDR(png, info,
                    &width, &height, &bit_depth, &color_type, &interlaced,
                    NULL, NULL)) goto Error;

  png_set_strip_16(png);
  png_set_packing(png);
  if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
  if (color_type == PNG_COLOR_TYPE_GRAY ||
      color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
    if (bit_depth < 8) {
      png_set_expand_gray_1_2_4_to_8(png);
    }
    png_set_gray_to_rgb(png);
  }
  if (png_get_valid(png, info, PNG_INFO_tRNS)) {
    png_set_tRNS_to_alpha(png);
    has_alpha = 1;
  } else {
    has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA);
  }


  num_passes = png_set_interlace_handling(png);
  png_read_update_info(png, info);
  stride = (has_alpha ? 4 : 3) * width * sizeof(*rgb);
  rgb = (uint8_t*)malloc(stride * height);
  if (rgb == NULL) goto Error;
  for (p = 0; p < num_passes; ++p) {
    for (y = 0; y < height; ++y) {
      png_bytep row = rgb + y * stride;
      png_read_rows(png, &row, NULL, 1);
    }
  }
  png_read_end(png, info);
  png_destroy_read_struct(&png, &info, NULL);

  image.width = width;
  image.height = height;
  image.image.realloc(height * width);
  for(size_t y = 0; y < height; y++)
	  for(size_t x = 0; x < width; x++){
		  size_t i = y * width + x;
		  if (has_alpha) {
			  *webp::utils::ALPHA(image.image[i]) = rgb[stride * y + x * 4];
			  *webp::utils::RED(image.image[i])   = rgb[stride * y + x * 4 + 1];
			  *webp::utils::GREEN(image.image[i]) = rgb[stride * y + x * 4 + 2];
			  *webp::utils::BLUE(image.image[i])  = rgb[stride * y + x * 4 + 3];
		  }
		  else{
			  *webp::utils::ALPHA(image.image[i]) = 0xFF;
			  *webp::utils::RED(image.image[i])   = rgb[stride * y + x * 3];
			  *webp::utils::GREEN(image.image[i]) = rgb[stride * y + x * 3 + 1];
			  *webp::utils::BLUE(image.image[i])  = rgb[stride * y + x * 3 + 2];
		  }
	  }
  free(rgb);
  
 End:
  fclose(fp);
  return ok;
}
/* Alternate create PNG structure for reading, and allocate any memory
 * needed.
 */
png_structp PNGAPI
png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
   png_malloc_ptr malloc_fn, png_free_ptr free_fn)
{
#endif /* PNG_USER_MEM_SUPPORTED */

#ifdef PNG_SETJMP_SUPPORTED
   volatile
#endif
   png_structp png_ptr;
   volatile int png_cleanup_needed = 0;

#ifdef PNG_SETJMP_SUPPORTED
#ifdef USE_FAR_KEYWORD
   jmp_buf jmpbuf;
#endif
#endif

   int i;

   png_debug(1, "in png_create_read_struct");

#ifdef PNG_USER_MEM_SUPPORTED
   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
      malloc_fn, mem_ptr);
#else
   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
#endif
   if (png_ptr == NULL)
      return (NULL);

   /* Added at libpng-1.2.6 */
#ifdef PNG_USER_LIMITS_SUPPORTED
   png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
   png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
#  ifdef PNG_USER_CHUNK_CACHE_MAX
   /* Added at libpng-1.2.43 and 1.4.0 */
   png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
#  endif
#  ifdef PNG_SET_USER_CHUNK_MALLOC_MAX
   /* Added at libpng-1.2.43 and 1.4.1 */
   png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
#  endif
#endif

#ifdef PNG_SETJMP_SUPPORTED
/* Applications that neglect to set up their own setjmp() and then
   encounter a png_error() will longjmp here.  Since the jmpbuf is
   then meaningless we abort instead of returning. */
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
#else
   if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */
#endif
      PNG_ABORT();
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_jmpbuf(png_ptr), jmpbuf, png_sizeof(jmp_buf));
#endif
#endif /* PNG_SETJMP_SUPPORTED */

#ifdef PNG_USER_MEM_SUPPORTED
   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
#endif

   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);

   if (user_png_ver)
   {
      i = 0;
      do
      {
         if (user_png_ver[i] != png_libpng_ver[i])
            png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
      } while (png_libpng_ver[i++]);
    }
    else
         png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;


    if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
    {
       /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
       * we must recompile any applications that use any older library version.
       * For versions after libpng 1.0, we will be compatible, so we need
       * only check the first digit.
       */
      if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
          (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
          (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
      {
#ifdef PNG_STDIO_SUPPORTED
         char msg[80];
         if (user_png_ver)
         {
           png_snprintf(msg, 80,
              "Application was compiled with png.h from libpng-%.20s",
              user_png_ver);
           png_warning(png_ptr, msg);
         }
         png_snprintf(msg, 80,
             "Application  is  running with png.c from libpng-%.20s",
             png_libpng_ver);
         png_warning(png_ptr, msg);
#endif
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
         png_ptr->flags = 0;
#endif
         png_warning(png_ptr,
            "Incompatible libpng version in application and library");

         png_cleanup_needed = 1;
      }
   }

   if (!png_cleanup_needed)
   {
   /* Initialize zbuf - compression buffer */
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
   png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr,
     png_ptr->zbuf_size);
   if (png_ptr->zbuf == NULL)
        png_cleanup_needed = 1;
   }
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;

   if (!png_cleanup_needed)
   {
      switch (inflateInit(&png_ptr->zstream))
      {
         case Z_OK: /* Do nothing */ break;
         case Z_MEM_ERROR:
         case Z_STREAM_ERROR: png_warning(png_ptr, "zlib memory error");
            png_cleanup_needed = 1; break;
         case Z_VERSION_ERROR: png_warning(png_ptr, "zlib version error");
            png_cleanup_needed = 1; break;
         default: png_warning(png_ptr, "Unknown zlib error");
            png_cleanup_needed = 1;
      }
   }

   if (png_cleanup_needed)
   {
      /* Clean up PNG structure and deallocate any memory. */
      png_free(png_ptr, png_ptr->zbuf);
      png_ptr->zbuf = NULL;
#ifdef PNG_USER_MEM_SUPPORTED
      png_destroy_struct_2((png_voidp)png_ptr,
         (png_free_ptr)free_fn, (png_voidp)mem_ptr);
#else
      png_destroy_struct((png_voidp)png_ptr);
#endif
      return (NULL);
   }

   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;

   png_set_read_fn(png_ptr, NULL, NULL);


   return (png_ptr);
}
Ejemplo n.º 30
0
void png_reader<T>::read(unsigned x0, unsigned y0,image_data_32& image)
{
    stream_.clear();
    stream_.seekg(0, std::ios_base::beg);

    png_structp png_ptr = png_create_read_struct
        (PNG_LIBPNG_VER_STRING,0,0,0);

    if (!png_ptr)
    {
        throw image_reader_exception("failed to allocate png_ptr");
    }

    // catch errors in a custom way to avoid the need for setjmp
    png_set_error_fn(png_ptr, png_get_error_ptr(png_ptr), user_error_fn, user_warning_fn);

    png_infop info_ptr;
    png_struct_guard sguard(&png_ptr,&info_ptr);
    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) throw image_reader_exception("failed to create info_ptr");

    png_set_read_fn(png_ptr, (png_voidp)&stream_, png_read_data);
    png_read_info(png_ptr, info_ptr);

    if (color_type_ == PNG_COLOR_TYPE_PALETTE)
        png_set_expand(png_ptr);
    if (color_type_ == PNG_COLOR_TYPE_GRAY && bit_depth_ < 8)
        png_set_expand(png_ptr);
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
        png_set_expand(png_ptr);
    if (bit_depth_ == 16)
        png_set_strip_16(png_ptr);
    if (color_type_ == PNG_COLOR_TYPE_GRAY ||
        color_type_ == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png_ptr);

    // quick hack -- only work in >=libpng 1.2.7
    png_set_add_alpha(png_ptr,0xff,PNG_FILLER_AFTER); //rgba

    double gamma;
    if (png_get_gAMA(png_ptr, info_ptr, &gamma))
        png_set_gamma(png_ptr, 2.2, gamma);

    if (x0 == 0 && y0 == 0 && image.width() >= width_ && image.height() >= height_)
    {

        if (png_get_interlace_type(png_ptr,info_ptr) == PNG_INTERLACE_ADAM7)
        {
            png_set_interlace_handling(png_ptr); // FIXME: libpng bug?
            // according to docs png_read_image
            // "..automatically handles interlacing,
            // so you don't need to call png_set_interlace_handling()"
        }
        png_read_update_info(png_ptr, info_ptr);
        // we can read whole image at once
        // alloc row pointers
        const std::unique_ptr<png_bytep[]> rows(new png_bytep[height_]);
        for (unsigned i=0; i<height_; ++i)
            rows[i] = (png_bytep)image.getRow(i);
        png_read_image(png_ptr, rows.get());
    }
    else
    {
        png_read_update_info(png_ptr, info_ptr);
        unsigned w=std::min(unsigned(image.width()),width_ - x0);
        unsigned h=std::min(unsigned(image.height()),height_ - y0);
        unsigned rowbytes=png_get_rowbytes(png_ptr, info_ptr);
        const std::unique_ptr<png_byte[]> row(new png_byte[rowbytes]);
        //START read image rows
        for (unsigned i = 0;i < height_; ++i)
        {
            png_read_row(png_ptr,row.get(),0);
            if (i >= y0 && i < (y0 + h))
            {
                image.setRow(i-y0,reinterpret_cast<unsigned*>(&row[x0 * 4]),w);
            }
        }
        //END
    }
    png_read_end(png_ptr,0);
}