Пример #1
0
  void storeFreeImage(const Ref<Image>& img, const FileName& fileName)
  {
      FIBITMAP* dib = FreeImage_Allocate((int)img->width, (int)img->height, 24);

      for(size_t y = 0; y < img->height; y++)
      {
          for(size_t x = 0; x < img->width; x++)
          {
			  Color4 c = img->get(x, y);
              
              RGBQUAD Value = {0};
              Value.rgbRed   = (BYTE)(clamp(c.r) * 255.0f);
              Value.rgbGreen = (BYTE)(clamp(c.g) * 255.0f);
              Value.rgbBlue  = (BYTE)(clamp(c.b) * 255.0f);

              FreeImage_SetPixelColor(dib, (unsigned int)x, (unsigned int)y, &Value);
          }
      }

      FIBITMAP* fiLogo = loadWatermark();

      unsigned int LogoWidth  = FreeImage_GetWidth (fiLogo);
      unsigned int LogoHeight = FreeImage_GetHeight(fiLogo);

      if(LogoWidth > img->width || LogoHeight > img->height)
      {
          FreeImage_Unload(fiLogo);

          FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(fileName.c_str());
          if(FreeImage_FIFSupportsWriting(fif))
              FreeImage_Save(fif, dib, fileName.c_str());

          FreeImage_Unload(dib);
      }
      else
      {
          int x_pos = (int)img->width  - LogoWidth;
          int y_pos = (int)img->height - LogoHeight;

          FIBITMAP* fiFG = FreeImage_Allocate((int)img->width, (int)img->height, 32);
          BOOL b = FreeImage_Paste(fiFG, fiLogo, x_pos, y_pos, 255);
          FreeImage_Unload(fiLogo);

          FIBITMAP* fiNew = FreeImage_Composite(fiFG, FALSE, NULL, dib);
          FreeImage_Unload(dib);

          FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(fileName.c_str());

          int save_flags = 0;
          if(fif == FIF_JPEG)
              save_flags = JPEG_QUALITYSUPERB | JPEG_BASELINE | JPEG_OPTIMIZE;

          if(FreeImage_FIFSupportsWriting(fif))
              FreeImage_Save(fif, fiNew, fileName.c_str(), save_flags);

          FreeImage_Unload(fiNew);
      }
  }
Пример #2
0
bool ImageLoaderFreeImage::loadInputImage(const QString &imageFileName, QString &errorMessage)
{
    bool result = false;

    FreeImageErrorMessage.clear();

    const FREE_IMAGE_FORMAT fileType = FreeImage_GetFileType(imageFileName.toAscii(), 0);
    FIBITMAP* newImage = FreeImage_Load(fileType, imageFileName.toAscii(), TIFF_CMYK|JPEG_CMYK);

    // Filter out images which FreeImage can load but not convert to Rgb24
    // And images which we simply don't handle
    if (newImage) {
        const FREE_IMAGE_TYPE type = FreeImage_GetImageType(newImage);
        if (type != FIT_BITMAP   // 1pbb Monochrome, 1-8bpp Palette, 8bpp Greyscale,
                                 // 24bpp Rgb, 32bpp Argb, 32bpp Cmyk
            && type != FIT_RGB16 // 16bpp Greyscale, 48bpp Rgb
            ) {
            FreeImage_Unload(newImage);
            newImage = NULL;
        }
    }

    if (newImage) {
        result = true;
        disposeImage();

        m_bitmap = newImage;

        m_widthPixels = FreeImage_GetWidth(m_bitmap);
        m_heightPixels = FreeImage_GetHeight(m_bitmap);

        m_horizontalDotsPerMeter = FreeImage_GetDotsPerMeterX(m_bitmap);
        m_verticalDotsPerMeter = FreeImage_GetDotsPerMeterY(m_bitmap);

        if (m_horizontalDotsPerMeter == 0)
            m_horizontalDotsPerMeter = 2835; // 72 dpi
        if (m_verticalDotsPerMeter == 0)
            m_verticalDotsPerMeter = 2835;

        m_imageFileName = imageFileName;

        if (colorDataType() == Types::ColorTypeRGB && bitsPerPixel() == 32) {
            // Sometimes, there are strange .PSD images like this (FreeImage bug?)
            RGBQUAD white = { 255, 255, 255, 0 };
            FIBITMAP *Image24Bit = FreeImage_Composite(m_bitmap, FALSE, &white);
            FreeImage_Unload(m_bitmap);
            m_bitmap = Image24Bit;
        }
    }

    errorMessage = FreeImageErrorMessage;

    return result;
}
Пример #3
0
/*
 * Arguments: dest. dib_udata, foreground dib_udata,
 *	[use_file_background (boolean), app_background_color (Color),
 *	background dib_udata]
 * Returns: [dest. dib_udata]
 */
static int
dib_composite (lua_State *L)
{
  FIBITMAP **dibp = checkudata(L, 1, DIB_TYPENAME);
  FIBITMAP *fg_dib = lua_unboxpointer(L, 2, DIB_TYPENAME);
  const BOOL use_file_bkg = lua_toboolean(L, 3);
  RGBQUAD app_bkcolor;
  const int i = lua_isnoneornil(L, 4)
   ? 0 : (lfi_tocolor(L, 4, &app_bkcolor), 1);
  FIBITMAP *bg_dib = lua_isuserdata(L, 4 + i)
   ? lua_unboxpointer(L, 4 + i, DIB_TYPENAME) : NULL;

  *dibp = FreeImage_Composite(fg_dib, use_file_bkg,
   i ? &app_bkcolor : NULL, bg_dib);
  return dib_checkerror(L, *dibp);
}
Пример #4
0
void fipWinImage::drawEx(HDC hDC, RECT& rcDest, BOOL useFileBkg, RGBQUAD *appBkColor, FIBITMAP *bg) const {
	// Convert to a standard bitmap if needed
	if(_bHasChanged) {
		if(_bDeleteMe) {
			FreeImage_Unload(_display_dib);
			_display_dib = NULL;
			_bDeleteMe = FALSE;
		}

		FREE_IMAGE_TYPE image_type = getImageType();
		if(image_type == FIT_BITMAP) {
			BOOL bHasBackground = FreeImage_HasBackgroundColor(_dib);
			BOOL bIsTransparent = FreeImage_IsTransparent(_dib);

			if(!bIsTransparent && (!bHasBackground || !useFileBkg)) {
				// Copy pointer
				_display_dib = _dib;
			}
			else {
				// Create the transparent / alpha blended image
				_display_dib = FreeImage_Composite(_dib, useFileBkg, appBkColor, bg);
				if(_display_dib) {
					// Remember to delete _display_dib
					_bDeleteMe = TRUE;
				} else {
					// Something failed: copy pointers
					_display_dib = _dib;
				}
			}
		} else {
			// Convert to a standard dib for display

			if(image_type == FIT_COMPLEX) {
				// Convert to type FIT_DOUBLE
				FIBITMAP *dib_double = FreeImage_GetComplexChannel(_dib, FICC_MAG);
				// Convert to a standard bitmap (linear scaling)
				_display_dib = FreeImage_ConvertToStandardType(dib_double, TRUE);
				// Free image of type FIT_DOUBLE
				FreeImage_Unload(dib_double);
			} else if((image_type == FIT_RGBF) || (image_type == FIT_RGB16)) {
				// Apply a tone mapping algorithm and convert to 24-bit 
				_display_dib = FreeImage_ToneMapping(_dib, _tmo, _tmo_param_1, _tmo_param_2);
			} else if(image_type == FIT_RGBA16) {
				// Convert to 32-bit
				FIBITMAP *dib32 = FreeImage_ConvertTo32Bits(_dib);
				if(dib32) {
					// Create the transparent / alpha blended image
					_display_dib = FreeImage_Composite(dib32, useFileBkg, appBkColor, bg);
					FreeImage_Unload(dib32);
				}
			} else {
				// Other cases: convert to a standard bitmap (linear scaling)
				_display_dib = FreeImage_ConvertToStandardType(_dib, TRUE);
			}
			// Remember to delete _display_dib
			_bDeleteMe = TRUE;
		}

		_bHasChanged = FALSE;
	}

	// Draw the dib
	SetStretchBltMode(hDC, COLORONCOLOR);	
	StretchDIBits(hDC, rcDest.left, rcDest.top, 
		rcDest.right-rcDest.left, rcDest.bottom-rcDest.top, 
		0, 0, FreeImage_GetWidth(_display_dib), FreeImage_GetHeight(_display_dib),
		FreeImage_GetBits(_display_dib), FreeImage_GetInfo(_display_dib), DIB_RGB_COLORS, SRCCOPY);

}
Пример #5
0
static void *bg_next_frame(void *data)
{
  struct imv_loader *ldr = data;

  pthread_mutex_lock(&ldr->lock);
  int num_frames = ldr->num_frames;
  if(num_frames < 2) {
    pthread_mutex_unlock(&ldr->lock);
    return NULL;
  }

  FITAG *tag = NULL;
  char disposal_method = 0;
  int frame_time = 0;
  short top = 0;
  short left = 0;

  ldr->cur_frame = ldr->next_frame;
  ldr->next_frame = (ldr->cur_frame + 1) % ldr->num_frames;
  FIBITMAP *frame = FreeImage_LockPage(ldr->mbmp, ldr->cur_frame);
  FIBITMAP *frame32 = FreeImage_ConvertTo32Bits(frame);

  /* First frame is always going to use the raw frame */
  if(ldr->cur_frame > 0) {
    FreeImage_GetMetadata(FIMD_ANIMATION, frame, "DisposalMethod", &tag);
    if(FreeImage_GetTagValue(tag)) {
      disposal_method = *(char*)FreeImage_GetTagValue(tag);
    }
  }

  FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameLeft", &tag);
  if(FreeImage_GetTagValue(tag)) {
    left = *(short*)FreeImage_GetTagValue(tag);
  }

  FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameTop", &tag);
  if(FreeImage_GetTagValue(tag)) {
    top = *(short*)FreeImage_GetTagValue(tag);
  }

  FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameTime", &tag);
  if(FreeImage_GetTagValue(tag)) {
    frame_time = *(int*)FreeImage_GetTagValue(tag);
  }

  /* some gifs don't provide a frame time at all */
  if(frame_time == 0) {
    frame_time = 100;
  }
  ldr->frame_time += frame_time * 0.001;

  FreeImage_UnlockPage(ldr->mbmp, frame, 0);

  /* If this frame is inset, we need to expand it for compositing */
  if(ldr->width != (int)FreeImage_GetWidth(frame32) ||
     ldr->height != (int)FreeImage_GetHeight(frame32)) {
    FIBITMAP *expanded = FreeImage_Allocate(ldr->width, ldr->height, 32, 0,0,0);
    FreeImage_Paste(expanded, frame32, left, top, 255);
    FreeImage_Unload(frame32);
    frame32 = expanded;
  }

  switch(disposal_method) {
    case 0: /* nothing specified, fall through to compositing */
    case 1: /* composite over previous frame */
      if(ldr->bmp && ldr->cur_frame > 0) {
        FIBITMAP *bg_frame = FreeImage_ConvertTo24Bits(ldr->bmp);
        FreeImage_Unload(ldr->bmp);
        FIBITMAP *comp = FreeImage_Composite(frame32, 1, NULL, bg_frame);
        FreeImage_Unload(bg_frame);
        FreeImage_Unload(frame32);
        ldr->bmp = comp;
      } else {
        /* No previous frame, just render directly */
        if(ldr->bmp) {
          FreeImage_Unload(ldr->bmp);
        }
        ldr->bmp = frame32;
      }
      break;
    case 2: /* TODO - set to background, composite over that */
      if(ldr->bmp) {
        FreeImage_Unload(ldr->bmp);
      }
      ldr->bmp = frame32;
      break;
    case 3: /* TODO - restore to previous content */
      if(ldr->bmp) {
        FreeImage_Unload(ldr->bmp);
      }
      ldr->bmp = frame32;
      break;
  }

  if(ldr->out_bmp) {
    FreeImage_Unload(ldr->out_bmp);
  }
  ldr->out_bmp = FreeImage_Clone(ldr->bmp);

  pthread_mutex_unlock(&ldr->lock);
  return NULL;
}
Пример #6
0
// parsePNGFile()
// Takes in a PNG file and plugs the indexes into
// the proper art format.
static bool parsePNGFile(uint32_t pngi, FILE* afile)
{
	FILE* pngfile;
	char pngfilename[FILENAME_MAX];
	uint8_t* buffer;
	uint32_t xsize, ysize;
	int32_t xi, yi;
	FIBITMAP *pngas;
	FIBITMAP *pngaspal;
	FIBITMAP *pngasbg;
	FIBITMAP *pngas24;
	FIBITMAP *pngastemp;
	uint32_t m;
	uint32_t n;
	uint32_t _px;
	uint32_t* _pbx;
	
	pngi;

	TilesList[pngi].animdata = 0;
	TilesList[pngi].offset = ftell(afile);
	TilesList[pngi].sizex = 0;
	TilesList[pngi].sizey = 0;

	sprintf(pngfilename, "%s%stile%04u.png", inputdir, PATH_DELIMITER, pngi);
	
	pngastemp = FreeImage_Load(FIF_PNG, pngfilename, 0);

	if (pngastemp == NULL)
		return false;
		
	pngas = FreeImage_AllocateEx(FreeImage_GetWidth(pngastemp), 
		FreeImage_GetHeight(pngastemp), 8, &rgbpal[255], 0, rgbpal, 0, 0, 0);

	FreeImage_FlipVertical(pngastemp);
	
	if (FreeImage_GetBPP(pngastemp) != 8)
	{
		// printf("ssssnaaaaoooo\n");
		
		if (FreeImage_GetBPP(pngastemp) == 32)
		{
			pngasbg = FreeImage_Composite(pngastemp, FALSE, &rgbpal[255], NULL);
			// pngas24 = FreeImage_ConvertTo24Bits(pngasbg);
			
			
			pngaspal = FreeImage_ColorQuantizeEx(pngasbg, FIQ_NNQUANT, 256, 256, rgbpal);
			FreeImage_SetTransparentIndex(pngaspal, 255);
		}
		else
		{
			pngaspal = FreeImage_ColorQuantizeEx(pngastemp, FIQ_NNQUANT, 256, 256, rgbpal);
			FreeImage_SetTransparentIndex(pngaspal, 255);
		}
		
		if (pngaspal == NULL)
		{
			printf("error: tile%04u.png is an invalid 8/24/32bit image\n", pngi);
			return false;
		}	
			
		pngas = pngaspal;
		
	}
	else
	{
		pngas = pngastemp;
	}
	
	xsize = FreeImage_GetWidth(pngas);
	ysize = FreeImage_GetHeight(pngas);

	TilesList[pngi].sizex = xsize;
	TilesList[pngi].sizey = ysize;

	buffer = malloc(xsize * ysize);
	
	if (buffer == NULL)
	{
		printf("error: not enough memory to read image\n");
		return false;
	}

	// This is where the magic happens
	for (xi = 0; xi  < TilesList[pngi].sizex; xi++)
	{
		for (yi = 0; yi < TilesList[pngi].sizey; yi++)
		{
			FreeImage_GetPixelIndex(pngas, xi, yi, &buffer[xi * TilesList[pngi].sizey + yi]);
			fwrite(&buffer[xi * TilesList[pngi].sizey + yi], 1, 1, afile);
		}
	}
	
	free(buffer);	// Gotta free memory explicitly

	return true;
}