Ejemplo n.º 1
0
	void SimpleSurface::applyFilter (Surface *inSrc, const Rect &inRect, ImagePoint inOffset, Filter *inFilter) {
		
		if (!mBase) return;
		FilterList f;
		f.push_back (inFilter);
		
		Rect src_rect (inRect.w, inRect.h);
		Rect dest = GetFilteredObjectRect (f, src_rect);
		
		inSrc->IncRef ();
		Surface *result = FilterBitmap (f, inSrc, src_rect, dest, false, ImagePoint (inRect.x, inRect.y));
		
		dest.Translate (inOffset.x, inOffset.y);
		
		src_rect = Rect (0, 0, result->Width (), result->Height ());
		int dx = dest.x;
		int dy = dest.y;
		dest = dest.Intersect (Rect (0, 0, mWidth, mHeight));
		dest.Translate (-dx, -dy);
		dest = dest.Intersect (src_rect);
		dest.Translate (dx, dy);
		
		int bpp = BytesPP ();
		
		RenderTarget t = BeginRender (dest, false);
		//printf("Copy back @ %d,%d %dx%d  + (%d,%d)\n", dest.x, dest.y, t.Width(), t.Height(), dx, dy);
		for (int y = 0; y < t.Height (); y++)
			memcpy ((void *)(t.Row (y + dest.y) + ((dest.x) * bpp)), result->Row (y - dy) - (dx * bpp), dest.w * bpp);
		
		EndRender ();
		
		result->DecRef ();
		
	}
Ejemplo n.º 2
0
static Surface *TryPNG(FILE *inFile,const uint8 *inData, int inDataLen)
{
   png_structp png_ptr;
   png_infop info_ptr;
   png_uint_32 width, height;
   int bit_depth, color_type, interlace_type;

   /* 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.  REQUIRED
    */
   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
      0, user_error_fn, user_warning_fn);

   if (png_ptr == NULL)
      return (0);

   /* Allocate/initialize the memory for image information.  REQUIRED. */
   info_ptr = png_create_info_struct(png_ptr);
   if (info_ptr == NULL)
   {
      png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
      return (0);
   }

   /* Set error handling if you are using the setjmp/longjmp method (this is
    * the normal method of doing things with libpng).  REQUIRED unless you
    * set up your own error handlers in the png_create_read_struct() earlier.
    */

   Surface *result = 0;
   RenderTarget target;

   if (setjmp(png_jmpbuf(png_ptr)))
   {
      if (result)
      {
         result->EndRender();
         result->DecRef();
      }

      /* 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 */
      return (0);
   }

   ReadBuf buffer(inData,inDataLen);
   if (inFile)
   {
      png_init_io(png_ptr, inFile);
   }
   else
   {
      png_set_read_fn(png_ptr,(void *)&buffer, user_read_data_fn);
   }

   png_read_info(png_ptr, info_ptr);

   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
       &interlace_type, NULL, NULL);

   bool has_alpha = color_type== PNG_COLOR_TYPE_GRAY_ALPHA ||
                    color_type==PNG_COLOR_TYPE_RGB_ALPHA ||
                    png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS);
   
   /* Add filler (or alpha) byte (before/after each RGB triplet) */
   png_set_expand(png_ptr);
   png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
   //png_set_gray_1_2_4_to_8(png_ptr);
   png_set_palette_to_rgb(png_ptr);
   png_set_gray_to_rgb(png_ptr);

   // Stripping 16 bits per channel to 8 bits per channel.
   if (bit_depth == 16)
      png_set_strip_16(png_ptr);

   png_set_bgr(png_ptr);

   result = new SimpleSurface(width,height, (has_alpha) ? pfARGB : pfXRGB);
   result->IncRef();
   target = result->BeginRender(Rect(width,height));
   
   /* if the image is interlaced, run multiple passes */
   int number_of_passes = png_set_interlace_handling(png_ptr);
   
   for (int pass = 0; pass < number_of_passes; pass++)
   {
      for (int i = 0; i < height; i++)
      {
         png_bytep anAddr = (png_bytep) target.Row(i);
         png_read_rows(png_ptr, (png_bytepp) &anAddr, NULL, 1);
      }
   }

   result->EndRender();

   /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
   png_read_end(png_ptr, info_ptr);

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

   /* that's it */
   return result;
}
Ejemplo n.º 3
0
static Surface *TryJPEG(FILE *inFile,const uint8 *inData, int inDataLen)
{
   struct jpeg_decompress_struct cinfo;

   // Don't exit on error!
   struct ErrorData jpegError;
   cinfo.err = jpeg_std_error(&jpegError.base);
   jpegError.base.error_exit = OnError;
   jpegError.base.output_message = OnOutput;

   Surface *result = 0;
   uint8 *row_buf = 0;

   // Establish the setjmp return context for ErrorFunction to use
   if (setjmp(jpegError.on_error))
   {
      if (row_buf)
         free(row_buf);
      if (result)
         result->DecRef();

      jpeg_destroy_decompress(&cinfo);
      return 0;
   }

   // Initialize the JPEG decompression object.
   jpeg_create_decompress(&cinfo);

   // Specify data source (ie, a file, or buffer)
   MySrcManager manager(inData,inDataLen);
   if (inFile)
      jpeg_stdio_src(&cinfo, inFile);
   else
   {
      cinfo.src = &manager.pub;
   }

   // Read file parameters with jpeg_read_header().
   if (jpeg_read_header(&cinfo, TRUE)!=JPEG_HEADER_OK)
      return 0;

   cinfo.out_color_space = JCS_RGB;

   // Start decompressor.
   jpeg_start_decompress(&cinfo);

   result = new SimpleSurface(cinfo.output_width, cinfo.output_height, pfXRGB);
   result->IncRef();


   RenderTarget target = result->BeginRender(Rect(cinfo.output_width, cinfo.output_height));


   row_buf = (uint8 *)malloc(cinfo.output_width * 3);

   while (cinfo.output_scanline < cinfo.output_height)
   {
      uint8 * src = row_buf;
      uint8 * dest = target.Row(cinfo.output_scanline);

      jpeg_read_scanlines(&cinfo, &row_buf, 1);

      uint8 *end = dest + cinfo.output_width*4;
      while (dest<end)
      {
         dest[0] = src[2];
         dest[1] = src[1];
         dest[2] = src[0];
         dest[3] = 0xff;
         dest+=4;
         src+=3;
      }
   }
   result->EndRender();

   free(row_buf);

   // Finish decompression.
   jpeg_finish_decompress(&cinfo);

   // Release JPEG decompression object
   jpeg_destroy_decompress(&cinfo);

   return result;
}