FIBITMAP* DLL_CALLCONV
FIA_ComplexImageToRealValued(FIBITMAP *src)
{
	FIBITMAP *dst = NULL;
	unsigned x, y;
						
	unsigned width	= FreeImage_GetWidth(src);
	unsigned height = FreeImage_GetHeight(src);

	// allocate a 8-bit dib
	dst = FreeImage_AllocateT(FIT_DOUBLE, width, height, 32, 0, 0, 0);
	
	if(!dst)
		return NULL;

	FICOMPLEX *src_bits; 	
	double	  *dst_bits; 

	for(y = 0; y < height; y++) { 
		
		src_bits = (FICOMPLEX *) FreeImage_GetScanLine(src, y);
		dst_bits = (double *) FreeImage_GetScanLine(dst, y);

		for(x=0; x < width; x++) {
			dst_bits[x] = (double) src_bits[x].r;
		}
	}

	return dst;
}
Example #2
0
template<class Tsrc> FIBITMAP* 
CONVERT_TO_COMPLEX<Tsrc>::convert(FIBITMAP *src) {
	FIBITMAP *dst = NULL;

	unsigned width	= FreeImage_GetWidth(src);
	unsigned height = FreeImage_GetHeight(src);

	// allocate dst image

	dst = FreeImage_AllocateT(FIT_COMPLEX, width, height);
	if(!dst) return NULL;

	// convert from src_type to FIT_COMPLEX
	
	for(unsigned y = 0; y < height; y++) {
		const Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
		FICOMPLEX *dst_bits = (FICOMPLEX *)FreeImage_GetScanLine(dst, y);

		for(unsigned x = 0; x < width; x++) {
			dst_bits[x].r = (double)src_bits[x];
			dst_bits[x].i = 0;
		}
	}

	return dst;
}
Example #3
0
template<class Tdst, class Tsrc> FIBITMAP* 
CONVERT_TYPE<Tdst, Tsrc>::convert(FIBITMAP *src, FREE_IMAGE_TYPE dst_type) {

	FIBITMAP *dst = NULL;

	unsigned width	= FreeImage_GetWidth(src);
	unsigned height = FreeImage_GetHeight(src);
	unsigned bpp	= FreeImage_GetBPP(src);

	// allocate dst image

	dst = FreeImage_AllocateT(dst_type, width, height, bpp, 
			FreeImage_GetRedMask(src), FreeImage_GetGreenMask(src), FreeImage_GetBlueMask(src));
	if(!dst) return NULL;

	// convert from src_type to dst_type
	
	for(unsigned y = 0; y < height; y++) {
		const Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
		Tdst *dst_bits = reinterpret_cast<Tdst*>(FreeImage_GetScanLine(dst, y));

		for(unsigned x = 0; x < width; x++) {
			*dst_bits++ = static_cast<Tdst>(*src_bits++);
		}
	}

	return dst;
}
Example #4
0
/** @brief Inverts each pixel data.

@param src Input image to be processed.
@return Returns TRUE if successful, FALSE otherwise.
*/
BOOL DLL_CALLCONV 
FreeImage_Invert(FIBITMAP *src) {
	unsigned i, x, y, k;
	BYTE *bits;

	if (!src) return FALSE;

	int bpp = FreeImage_GetBPP(src);
	
	switch(bpp) {
        case 1 :
		case 4 :
		case 8 :
		{
			// if the dib has a colormap, just invert it
			// else, keep the linear grayscale

			if (FreeImage_GetColorType(src) == FIC_PALETTE) {
				RGBQUAD *pal = FreeImage_GetPalette(src);

				for(i = 0; i < FreeImage_GetColorsUsed(src); i++) {
					pal[i].rgbRed	= 255 - pal[i].rgbRed;
					pal[i].rgbGreen = 255 - pal[i].rgbGreen;
					pal[i].rgbBlue	= 255 - pal[i].rgbBlue;
				}
			} else {
				for(y = 0; y < FreeImage_GetHeight(src); y++) {
					bits = FreeImage_GetScanLine(src, y);

					for (x = 0; x < FreeImage_GetLine(src); x++) {
						bits[x] = ~bits[x];
					}
				}
			}

			break;
		}		

		case 24 :
		case 32 :
		{
			unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src);

			for(y = 0; y < FreeImage_GetHeight(src); y++) {
				bits =  FreeImage_GetScanLine(src, y);
				for(x = 0; x < FreeImage_GetWidth(src); x++) {
					for(k = 0; k < bytespp; k++) {
						bits[k] = ~bits[k];
					}
					bits += bytespp;
				}
			}

			break;
		}

	}
	return TRUE;
}
/**
Solution of the model problem on the coarsest grid, where h = 1/2 . 
The right-hand side is input
in rhs[0..2][0..2] and the solution is returned in u[0..2][0..2].
*/
static void fmg_solve(FIBITMAP *U, FIBITMAP *RHS) {
	// fill U with zeros
	fmg_fillArrayWithZeros(U);
	// calculate U(1, 1) = -h*h*RHS(1, 1)/4.0 where h = 1/2
	float *u_scan = (float*)FreeImage_GetScanLine(U, 1);
	const float *rhs_scan = (float*)FreeImage_GetScanLine(RHS, 1);
	u_scan[1] = -rhs_scan[1] / 16;
}
Example #6
0
/** @brief Retrieves the red, green, blue or alpha channel of a 24- or 32-bit BGR[A] image. 
@param src Input image to be processed.
@param channel Color channel to extract
@return Returns the extracted channel if successful, returns NULL otherwise.
*/
FIBITMAP * DLL_CALLCONV 
FreeImage_GetChannel(FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel) {
	int c;

	if(!src) return NULL;

	unsigned bpp = FreeImage_GetBPP(src);
	if((bpp == 24) || (bpp == 32)) {
		// select the channel to extract
		switch(channel) {
			case FICC_BLUE:
				c = FI_RGBA_BLUE;
				break;
			case FICC_GREEN:
				c = FI_RGBA_GREEN;
				break;
			case FICC_RED: 
				c = FI_RGBA_RED;
				break;
			case FICC_ALPHA:
				if(bpp != 32) return NULL;
				c = FI_RGBA_ALPHA;
				break;
			default:
				return NULL;
		}

		// allocate a 8-bit dib
		unsigned width  = FreeImage_GetWidth(src);
		unsigned height = FreeImage_GetHeight(src);
		FIBITMAP *dst = FreeImage_Allocate(width, height, 8) ;
		if(!dst) return NULL;
		// build a greyscale palette
		RGBQUAD *pal = FreeImage_GetPalette(dst);
		for(int i = 0; i < 256; i++) {
			pal[i].rgbBlue = pal[i].rgbGreen = pal[i].rgbRed = i;
		}

		// perform extraction

		int bytespp = bpp / 8;	// bytes / pixel

		for(unsigned y = 0; y < height; y++) {
			BYTE *src_bits = FreeImage_GetScanLine(src, y);
			BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
			for(unsigned x = 0; x < width; x++) {
				dst_bits[x] = src_bits[c];
				src_bits += bytespp;
			}
		}

		return dst;
	}

	return NULL;
}
Example #7
0
/**
Save using EXR_LC compression (works only with RGB[A]F images)
*/
static BOOL
SaveAsEXR_LC(C_OStream& ostream, FIBITMAP *dib, Imf::Header& header, int width, int height) {
    int x, y;
    Imf::RgbaChannels rgbaChannels;

    try {

        FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);

        // convert from float to half
        Imf::Array2D<Imf::Rgba> pixels(height, width);
        switch(image_type) {
        case FIT_RGBF:
            rgbaChannels = Imf::WRITE_YC;
            for(y = 0; y < height; y++) {
                FIRGBF *src_bits = (FIRGBF*)FreeImage_GetScanLine(dib, height - 1 - y);
                for(x = 0; x < width; x++) {
                    Imf::Rgba &dst_bits = pixels[y][x];
                    dst_bits.r = src_bits[x].red;
                    dst_bits.g = src_bits[x].green;
                    dst_bits.b = src_bits[x].blue;
                }
            }
            break;
        case FIT_RGBAF:
            rgbaChannels = Imf::WRITE_YCA;
            for(y = 0; y < height; y++) {
                FIRGBAF *src_bits = (FIRGBAF*)FreeImage_GetScanLine(dib, height - 1 - y);
                for(x = 0; x < width; x++) {
                    Imf::Rgba &dst_bits = pixels[y][x];
                    dst_bits.r = src_bits[x].red;
                    dst_bits.g = src_bits[x].green;
                    dst_bits.b = src_bits[x].blue;
                    dst_bits.a = src_bits[x].alpha;
                }
            }
            break;
        default:
            THROW (Iex::IoExc, "Bad image type");
            break;
        }

        // write the data
        Imf::RgbaOutputFile file(ostream, header, rgbaChannels);
        file.setFrameBuffer (&pixels[0][0], 1, width);
        file.writePixels (height);

        return TRUE;

    } catch(Iex::BaseExc & e) {
        FreeImage_OutputMessageProc(s_format_id, e.what());

        return FALSE;
    }

}
/* dt of 2d function using squared distance */
static void
dt2d (FIBITMAP * src)
{
    int width = FreeImage_GetWidth (src);
    int height = FreeImage_GetHeight (src);
    float *f = new float[MAX (width, height)];
    register int x, y;

    register float *src_ptr;

    // transform along columns
    for(x = 0; x < width; x++)
    {
        for(y = 0; y < height; y++)
        {

            src_ptr = (float *) FreeImage_GetScanLine (src, y);
            f[y] = src_ptr[x];
        }

        float *d = dt (f, height);

        for(y = 0; y < height; y++)
        {

            src_ptr = (float *) FreeImage_GetScanLine (src, y);
            src_ptr[x] = d[y];
        }

        delete[]d;
    }

    // transform along rows
    for(y = 0; y < height; y++)
    {
        src_ptr = (float *) FreeImage_GetScanLine (src, y);

        for(x = 0; x < width; x++)
        {
            f[x] = src_ptr[x];
        }

        float *d = dt (f, width);

        for(x = 0; x < width; x++)
        {
            src_ptr[x] = d[x];
        }

        delete[]d;
    }

    delete f;
}
Example #9
0
/** @brief Insert a 8-bit dib into a 24- or 32-bit image. 
Both src and dst must have the same width and height.
@param dst Image to modify (24- or 32-bit)
@param src Input 8-bit image to insert
@param channel Color channel to modify
@return Returns TRUE if successful, FALSE otherwise.
*/
BOOL DLL_CALLCONV 
FreeImage_SetChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel) {
	int c;

	if(!src || !dst) return FALSE;

	// src image should be grayscale, dst image should be 24- or 32-bit
	unsigned src_bpp = FreeImage_GetBPP(src);
	unsigned dst_bpp = FreeImage_GetBPP(dst);
	if((src_bpp != 8) || (dst_bpp != 24) && (dst_bpp != 32))
		return FALSE;

	// src and dst images should have the same width and height
	unsigned src_width  = FreeImage_GetWidth(src);
	unsigned src_height = FreeImage_GetHeight(src);
	unsigned dst_width  = FreeImage_GetWidth(dst);
	unsigned dst_height = FreeImage_GetHeight(dst);
	if((src_width != dst_width) || (src_height != dst_height))
		return FALSE;

	// select the channel to modify
	switch(channel) {
		case FICC_BLUE:
			c = FI_RGBA_BLUE;
			break;
		case FICC_GREEN:
			c = FI_RGBA_GREEN;
			break;
		case FICC_RED: 
			c = FI_RGBA_RED;
			break;
		case FICC_ALPHA:
			if(dst_bpp != 32) return FALSE;
			c = FI_RGBA_ALPHA;
			break;
		default:
			return FALSE;
	}

	// perform insertion

	int bytespp = dst_bpp / 8;	// bytes / pixel

	for(unsigned y = 0; y < dst_height; y++) {
		BYTE *src_bits = FreeImage_GetScanLine(src, y);
		BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
		for(unsigned x = 0; x < dst_width; x++) {
			dst_bits[c] = src_bits[x];
			dst_bits += bytespp;
		}
	}

	return TRUE;
}
Example #10
0
/**
Convert a processed raw image to a FIBITMAP
@param image Processed raw image
@return Returns the converted dib if successfull, returns NULL otherwise
@see libraw_LoadEmbeddedPreview
*/
static FIBITMAP * 
libraw_ConvertProcessedImageToDib(libraw_processed_image_t *image) {
	FIBITMAP *dib = NULL;

	try {
		unsigned width = image->width;
		unsigned height = image->height;
		unsigned bpp = image->bits;
		if(bpp == 16) {
			// allocate output dib
			dib = FreeImage_AllocateT(FIT_RGB16, width, height);
			if(!dib) {
				throw FI_MSG_ERROR_DIB_MEMORY;
			}
			// write data
			WORD *raw_data = (WORD*)image->data;
			for(unsigned y = 0; y < height; y++) {
				FIRGB16 *output = (FIRGB16*)FreeImage_GetScanLine(dib, height - 1 - y);
				for(unsigned x = 0; x < width; x++) {
					output[x].red   = raw_data[0];
					output[x].green = raw_data[1];
					output[x].blue  = raw_data[2];
					raw_data += 3;
				}
			}
		} else if(bpp == 8) {
			// allocate output dib
			dib = FreeImage_AllocateT(FIT_BITMAP, width, height, 24);
			if(!dib) {
				throw FI_MSG_ERROR_DIB_MEMORY;
			}
			// write data
			BYTE *raw_data = (BYTE*)image->data;
			for(unsigned y = 0; y < height; y++) {
				RGBTRIPLE *output = (RGBTRIPLE*)FreeImage_GetScanLine(dib, height - 1 - y);
				for(unsigned x = 0; x < width; x++) {
					output[x].rgbtRed   = raw_data[0];
					output[x].rgbtGreen = raw_data[1];
					output[x].rgbtBlue  = raw_data[2];
					raw_data += 3;
				}
			}
		}
		
		return dib;

	} catch(const char *text) {
		FreeImage_Unload(dib);
		FreeImage_OutputMessageProc(s_format_id, text);
		return NULL;
	}
}
static FIBITMAP*
ConvertComplexImageToAbsoluteValued(FIBITMAP *src, bool squared)
{
	FIBITMAP *dst = NULL;
	unsigned x, y;
						
	unsigned width	= FreeImage_GetWidth(src);
	unsigned height = FreeImage_GetHeight(src);

	// Allocate a double bit dib
	dst = FreeImage_AllocateT(FIT_DOUBLE, width, height, 32, 0, 0, 0);
	
	if(!dst)
		return NULL;

	FICOMPLEX *src_bits, *src_bit; 	
	double	  *dst_bits; 

	if(squared) {

		for(y = 0; y < height; y++) { 
		
			src_bits = (FICOMPLEX *) FreeImage_GetScanLine(src, y);
			dst_bits = (double *) FreeImage_GetScanLine(dst, y);

			for(x=0; x < width; x++) {
				
                src_bit = src_bits + x;

				*(dst_bits + x) = (double) ((src_bit->r * src_bit->r) + (src_bit->i * src_bit->i));
			}
		}
	}
	else {

		for(y = 0; y < height; y++) { 
		
			src_bits = (FICOMPLEX *) FreeImage_GetScanLine(src, y);
			dst_bits = (double *) FreeImage_GetScanLine(dst, y);

			for(x=0; x < width; x++) {
				
                src_bit = src_bits + x;

				*(dst_bits + x) = sqrt((double) ((src_bit->r * src_bit->r) + (src_bit->i * src_bit->i)));
			}
		}
	}

	return dst;
}
/**
Returns minus the residual for the model problem. Input quantities are u[0..n-1][0..n-1] and
rhs[0..n-1][0..n-1], while res[0..n-1][0..n-1] is returned.
*/
static void fmg_residual(FIBITMAP *RES, FIBITMAP *U, FIBITMAP *RHS, int n) {
	int row, col;

	const float h = 1.0F / (n-1);	
	const float h2i = 1.0F / (h*h);

	const int res_pitch  = FreeImage_GetPitch(RES) / sizeof(float);
	const int u_pitch  = FreeImage_GetPitch(U) / sizeof(float);
	const int rhs_pitch  = FreeImage_GetPitch(RHS) / sizeof(float);
	
	float *res_bits = (float*)FreeImage_GetBits(RES);
	const float *u_bits = (float*)FreeImage_GetBits(U);
	const float *rhs_bits = (float*)FreeImage_GetBits(RHS);

	// interior points
	{
		float *res_scan = res_bits + res_pitch;
		const float *u_scan = u_bits + u_pitch;
		const float *rhs_scan = rhs_bits + rhs_pitch;
		for (row = 1; row < n-1; row++) {
			for (col = 1; col < n-1; col++) {
				// calculate RES(row, col) = 
				// -h2i * [ U(row+1, col) + U(row-1, col) + U(row, col+1) + U(row, col-1) - 4 * U(row, col) ] + RHS(row, col);
				float *res_center = res_scan + col;
				const float *u_center = u_scan + col;
				const float *rhs_center = rhs_scan + col;
				*res_center = *(u_center + u_pitch) + *(u_center - u_pitch) + *(u_center + 1) + *(u_center - 1) - 4 * *u_center;
				*res_center *= -h2i;
				*res_center += *rhs_center;
			}
			res_scan += res_pitch;
			u_scan += u_pitch;
			rhs_scan += rhs_pitch;
		}
	}

	// boundary points
	{
		memset(FreeImage_GetScanLine(RES, 0), 0, FreeImage_GetPitch(RES));
		memset(FreeImage_GetScanLine(RES, n-1), 0, FreeImage_GetPitch(RES));
		float *left = res_bits;
		float *right = res_bits + (n-1);
		for(int k = 0; k < n; k++) {
			*left = 0;
			*right = 0;
			left += res_pitch;
			right += res_pitch;
		}
	}
}
static inline void
CopyImageRow (FIBITMAP * src, int src_row, int row_start, int count)
{
    int pitch = FreeImage_GetPitch (src);

    BYTE *src_bits, *dst_bits;

    src_bits = FreeImage_GetScanLine (src, src_row);

    for(int y = row_start; y < (row_start + count); y++)
    {
        dst_bits = FreeImage_GetScanLine (src, y);
        memcpy (dst_bits, src_bits, pitch);
    }
}
/* dt of binary image using squared distance */
FIBITMAP *DLL_CALLCONV
FIA_DistanceTransform (FIBITMAP * src)
{
    int width = FreeImage_GetWidth (src);
    int height = FreeImage_GetHeight (src);
    float *out_ptr;
    unsigned char *src_ptr;

    FIBITMAP *out = FIA_ConvertToGreyscaleFloatType (src, FIT_FLOAT);

    for(register int y = 0; y < height; y++)
    {
        src_ptr = (unsigned char *) FreeImage_GetScanLine (src, y);
        out_ptr = (float *) FreeImage_GetScanLine (out, y);

        for(register int x = 0; x < width; x++)
        {

            if (src_ptr[x] == 0)
            {
                out_ptr[x] = 0.0f;
            }
            else
            {
                out_ptr[x] = INF;
            }
        }
    }

    dt2d (out);

    // take square roots
    for(register int y = 0; y < height; y++)
    {
        out_ptr = (float *) FreeImage_GetScanLine (out, y);

        for(register int x = 0; x < width; x++)
        {
            out_ptr[x] = sqrt (out_ptr[x]);
        }
    }

    FIBITMAP *ret = FreeImage_ConvertToStandardType (out, 1);

    FreeImage_Unload (out);

    return ret;
}
Example #15
0
bool LoadImage(FIBITMAP* image, Graphics::TBitmap* picture)
{
	picture->FreeImage();
	picture->PixelFormat = pf32bit;
	picture->Width = FreeImage_GetWidth(image);
	picture->Height = FreeImage_GetHeight(image);

	RGBQUAD *row1, *row2;

	for(int i(0); i < picture->Height; ++i)
	{
		row1 = (RGBQUAD *)FreeImage_GetScanLine(image,i);
		row2 = (RGBQUAD *)picture->ScanLine[picture->Height-1-i];		
		
		if(!row1 || !row2) return false;
		
		for(int j(0); j < picture->Width; ++j)
		{
			row2[j].rgbRed = row1[j].rgbRed;
			row2[j].rgbGreen = row1[j].rgbGreen;
			row2[j].rgbBlue = row1[j].rgbBlue;
		}
	}
	
	return true;
}
Example #16
0
  void write_image(const string& file, const SampleBuffer& buffer)
  {
    const float samples = static_cast<float>(buffer.samples());
    FIBITMAP* dib = FreeImage_Allocate(buffer.width(), buffer.height(),
        32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);

    const unsigned int BYTESPP =
      FreeImage_GetLine(dib) / FreeImage_GetWidth(dib);
    for (unsigned int y = 0; y < FreeImage_GetHeight(dib); ++y) {
      BYTE* bits = FreeImage_GetScanLine(dib, y);

      for (unsigned int x = 0; x < FreeImage_GetWidth(dib); ++x) {
        vec3 c = gamma_correct(buffer.get(x, y) / samples) * 255.0f;
        bits[FI_RGBA_RED]   = static_cast<BYTE>(c.r);
        bits[FI_RGBA_GREEN] = static_cast<BYTE>(c.g);
        bits[FI_RGBA_BLUE]  = static_cast<BYTE>(c.b);
        bits[FI_RGBA_ALPHA] = 255;

        bits += BYTESPP;
      }
    }

    if (!FreeImage_Save(FIF_PNG, dib, file.c_str(), 0)) {
      string err = "Failed to save screenshot to file '";
      err += file;
      err += '\'';
      throw err;
    }

    FreeImage_Unload(dib);
  }
Example #17
0
void poImage::setPixel(poPoint p, poColor c) {
	if(p.x < 0 || p.y < 0 || p.x >= getWidth() || p.y >=getHeight())
		return;
	
	uint x = p.x;
	uint y = p.y;
	
	BYTE *bits = FreeImage_GetScanLine(bitmap, y);
	switch(getChannels()) {
		case 1:
			bits[x] = (((0.21*c.R) + (0.71*c.G) + (0.07*c.B)) * c.A) * 255;
			break;
		case 2:
			bits[x*2] = ((0.21*c.R) + (0.71*c.G) + (0.07*c.B)) * 255;
			bits[x*2+1] = c.A * 255;
			break;
		case 3:
			bits[x*3] = c.R * c.A * 255;
			bits[x*3+1] = c.G * c.A * 255;
			bits[x*3+2] = c.B * c.A * 255;
			break;
		case 4:
			bits[x*4] = c.R * 255;
			bits[x*4+1] = c.G * 255;
			bits[x*4+2] = c.B * 255;
			bits[x*4+3] = c.A * 255;
			break;
	}
}
Example #18
0
bool RGBAImage::WriteToFile(const char* filename)
{
	const FREE_IMAGE_FORMAT fileType = FreeImage_GetFIFFromFilename(filename);
	if(FIF_UNKNOWN == fileType)
	{
		printf("Can't save to unknown filetype %s\n", filename);
		return false;
	}

	FIBITMAP* bitmap = FreeImage_Allocate(Width, Height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000);
	if(!bitmap)
	{
		printf("Failed to create freeimage for %s\n", filename);
		return false;
	}

	const unsigned int* source = Data;
	for( int y=0; y < Height; y++, source += Width )
	{
		unsigned int* scanline = (unsigned int*)FreeImage_GetScanLine(bitmap, Height - y - 1 );
		memcpy(scanline, source, sizeof(source[0]) * Width);
	}

	FreeImage_SetTransparent(bitmap, true);
	FIBITMAP* converted = FreeImage_ConvertTo24Bits(bitmap);


	const bool result = !!FreeImage_Save(fileType, converted, filename);
	if(!result)
		printf("Failed to save to %s\n", filename);

	FreeImage_Unload(converted);
	FreeImage_Unload(bitmap);
	return result;
}
Example #19
0
/**
Used for all 32 and 24 bit loading of uncompressed images
*/
static void 
loadTrueColor(FIBITMAP* dib, int width, int height, int file_pixel_size, FreeImageIO* io, fi_handle handle, BOOL as24bit) {
	const int pixel_size = as24bit ? 3 : file_pixel_size;

	// input line cache
	BYTE* file_line = (BYTE*)malloc( width * file_pixel_size);

	if (!file_line) {
		throw FI_MSG_ERROR_MEMORY;
	}

	for (int y = 0; y < height; y++) {
		BYTE *bits = FreeImage_GetScanLine(dib, y);
		io->read_proc(file_line, file_pixel_size, width, handle);
		BYTE *bgra = file_line;

		for (int x = 0; x < width; x++) {

			bits[FI_RGBA_BLUE]	= bgra[0];
			bits[FI_RGBA_GREEN] = bgra[1];
			bits[FI_RGBA_RED]	= bgra[2];

			if (!as24bit) {
				bits[FI_RGBA_ALPHA] = bgra[3];
			}

			bgra += file_pixel_size;

			bits += pixel_size;
		}
	}

	free(file_line);
}
Example #20
0
FIBITMAP* TargaThumbnail::toFIBITMAP() {
	if(isNull() || _depth == 0) {
		return NULL;
	}
		
	const unsigned line_size = _depth * _w / 8;
	FIBITMAP* dib = FreeImage_Allocate(_w, _h, _depth);
	if(!dib) {
		return NULL;
	}

	const BYTE* line = _data;
	const BYTE height = _h;
	for (BYTE h = 0; h < height; ++h, line += line_size) {
		BYTE* dst_line = FreeImage_GetScanLine(dib, height - 1 - h);
		memcpy(dst_line, line, line_size);
	}

#ifdef FREEIMAGE_BIGENDIAN
	swapShortPixels(dib);
#endif
	
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
	SwapRedBlue32(dib);
#endif

	return dib;
}
Example #21
0
/**
Invert only color components, skipping Alpha/Black
(Can be useful as public/utility function)
*/
static
BOOL invertColor(FIBITMAP* dib) {
	FREE_IMAGE_TYPE type = FreeImage_GetImageType(dib);
	const unsigned Bpp = FreeImage_GetBPP(dib)/8;
	
	if((type == FIT_BITMAP && Bpp == 4) || type == FIT_RGBA16) {
		const unsigned width = FreeImage_GetWidth(dib);
		const unsigned height = FreeImage_GetHeight(dib);
		BYTE *line_start = FreeImage_GetScanLine(dib, 0);
		const unsigned pitch = FreeImage_GetPitch(dib);
		const unsigned triBpp = Bpp - (Bpp == 4 ? 1 : 2);
				
		for(unsigned y = 0; y < height; y++) {
			BYTE *line = line_start;

			for(unsigned x = 0; x < width; x++) {
				for(unsigned b=0; b < triBpp; ++b) {
					line[b] = ~line[b];
				}
					
				line += Bpp;
			}
			line_start += pitch;
		}
		
		return TRUE;
	}
	else {
		return FreeImage_Invert(dib);
	}
}
Example #22
0
poColor poImage::getPixel(poPoint p) const {
        
	if(!isValid() || p.x < 0 || p.y < 0 || p.x >= getWidth() || p.y >=getHeight())
		return poColor();

	uint x = p.x;
	uint y = p.y;
	
	BYTE* bits = FreeImage_GetScanLine(bitmap, y);
	poColor ret;
	
	switch(getChannels()) {
		case 1:
			ret.set255(bits[x], bits[x], bits[x], 255);
			break;
		case 2:
			ret.set255(bits[x*2], bits[x*2], bits[x*2], bits[x*2+1]);
			break;
		case 3:
			ret.set255(bits[x*3+0], bits[x*3+1], bits[x*3+2], 255);
			break;
		case 4:
			ret.set255(bits[x*4+0], bits[x*4+1], bits[x*4+2], bits[x*4+3]);
			break;
		default:
			;
	}
	
	return ret;
}
static BOOL DLL_CALLCONV
Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
	if(!dib) return FALSE;

	if(FreeImage_GetImageType(dib) != FIT_RGBF)
		return FALSE;

	unsigned width  = FreeImage_GetWidth(dib);
	unsigned height = FreeImage_GetHeight(dib);

	// write the header

	rgbeHeaderInfo header_info;
	memset(&header_info, 0, sizeof(rgbeHeaderInfo));
	// fill the header with correct gamma and exposure
	rgbe_WriteMetadata(dib, &header_info);
	// fill a comment
	sprintf(header_info.comment, "# Made with FreeImage %s", FreeImage_GetVersion());
	if(!rgbe_WriteHeader(io, handle, width, height, &header_info)) {
		return FALSE;
	}

	// write each scanline

	for(unsigned y = 0; y < height; y++) {
		FIRGBF *scanline = (FIRGBF*)FreeImage_GetScanLine(dib, height - 1 - y);
		if(!rgbe_WritePixels_RLE(io, handle, scanline, width, 1)) {
			return FALSE;
		}
	}

	return TRUE;
}
Example #24
0
/**
Pre-multiplies a 32-bit image's red-, green- and blue channels with it's alpha channel 
for to be used with e.g. the Windows GDI function AlphaBlend(). 
The transformation changes the red-, green- and blue channels according to the following equation:  
channel(x, y) = channel(x, y) * alpha_channel(x, y) / 255  
@param dib Input/Output dib to be premultiplied
@return Returns TRUE on success, FALSE otherwise (e.g. when the bitdepth of the source dib cannot be handled). 
*/
BOOL DLL_CALLCONV 
FreeImage_PreMultiplyWithAlpha(FIBITMAP *dib) {
	if (!FreeImage_HasPixels(dib)) return FALSE;
	
	if ((FreeImage_GetBPP(dib) != 32) || (FreeImage_GetImageType(dib) != FIT_BITMAP)) {
		return FALSE;
	}

	int width = FreeImage_GetWidth(dib);
	int height = FreeImage_GetHeight(dib);

	for(int y = 0; y < height; y++) {
		BYTE *bits = FreeImage_GetScanLine(dib, y);
		for (int x = 0; x < width; x++, bits += 4) {
			const BYTE alpha = bits[FI_RGBA_ALPHA];
			// slightly faster: care for two special cases
			if(alpha == 0x00) {
				// special case for alpha == 0x00
				// color * 0x00 / 0xFF = 0x00
				bits[FI_RGBA_BLUE] = 0x00;
				bits[FI_RGBA_GREEN] = 0x00;
				bits[FI_RGBA_RED] = 0x00;
			} else if(alpha == 0xFF) {
				// nothing to do for alpha == 0xFF
				// color * 0xFF / 0xFF = color
				continue;
			} else {
				bits[FI_RGBA_BLUE] = (BYTE)( (alpha * (WORD)bits[FI_RGBA_BLUE] + 127) / 255 );
				bits[FI_RGBA_GREEN] = (BYTE)( (alpha * (WORD)bits[FI_RGBA_GREEN] + 127) / 255 );
				bits[FI_RGBA_RED] = (BYTE)( (alpha * (WORD)bits[FI_RGBA_RED] + 127) / 255 );
			}
		}
	}
	return TRUE;
}
Example #25
0
/**
Load uncompressed image pixels for 1-, 4-, 8-, 16-, 24- and 32-bit dib
@param io FreeImage IO
@param handle FreeImage IO handle
@param dib Image to be loaded 
@param height Image height
@param pitch Image pitch
@param bit_count Image bit-depth (1-, 4-, 8-, 16-, 24- or 32-bit)
@return Returns TRUE if successful, returns FALSE otherwise
*/
static BOOL 
LoadPixelData(FreeImageIO *io, fi_handle handle, FIBITMAP *dib, int height, unsigned pitch, unsigned bit_count) {
	unsigned count = 0;

	// Load pixel data
	// NB: height can be < 0 for BMP data
	if (height > 0) {
		count = io->read_proc((void *)FreeImage_GetBits(dib), height * pitch, 1, handle);
		if(count != 1) {
			return FALSE;
		}
	} else {
		int positiveHeight = abs(height);
		for (int c = 0; c < positiveHeight; ++c) {
			count = io->read_proc((void *)FreeImage_GetScanLine(dib, positiveHeight - c - 1), pitch, 1, handle);
			if(count != 1) {
				return FALSE;
			}
		}
	}

	// swap as needed
#ifdef FREEIMAGE_BIGENDIAN
	if (bit_count == 16) {
		for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
			WORD *pixel = (WORD *)FreeImage_GetScanLine(dib, y);
			for(unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
				SwapShort(pixel);
				pixel++;
			}
		}
	}
#endif
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
	if (bit_count == 24 || bit_count == 32) {
		for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
			BYTE *pixel = FreeImage_GetScanLine(dib, y);
			for(unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
				INPLACESWAP(pixel[0], pixel[2]);
				pixel += (bit_count >> 3);
			}
		}
	}
#endif

	return TRUE;
}
Example #26
0
/** @brief Set the real or imaginary part of a complex image.
Both src and dst must have the same width and height.
@param dst Image to modify (image of type FIT_COMPLEX)
@param src Input image of type FIT_DOUBLE
@param channel Channel to modify
@return Returns TRUE if successful, FALSE otherwise.
*/
BOOL DLL_CALLCONV 
FreeImage_SetComplexChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel) {
	unsigned x, y;
	double *src_bits = NULL;
	FICOMPLEX *dst_bits = NULL;

	if(!src || !dst) return FALSE;

	// src image should be of type FIT_DOUBLE, dst image should be of type FIT_COMPLEX
	FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(src);
	FREE_IMAGE_TYPE dst_type = FreeImage_GetImageType(dst);
	if((src_type != FIT_DOUBLE) || (dst_type != FIT_COMPLEX))
		return FALSE;

	// src and dst images should have the same width and height
	unsigned src_width  = FreeImage_GetWidth(src);
	unsigned src_height = FreeImage_GetHeight(src);
	unsigned dst_width  = FreeImage_GetWidth(dst);
	unsigned dst_height = FreeImage_GetHeight(dst);
	if((src_width != dst_width) || (src_height != dst_height))
		return FALSE;

	// select the channel to modify
	switch(channel) {
		case FICC_REAL: // real part
			for(y = 0; y < dst_height; y++) {
				src_bits = (double *)FreeImage_GetScanLine(src, y);
				dst_bits = (FICOMPLEX *)FreeImage_GetScanLine(dst, y);
				for(x = 0; x < dst_width; x++) {
					dst_bits[x].r = src_bits[x];
				}
			}
			break;
		case FICC_IMAG: // imaginary part
			for(y = 0; y < dst_height; y++) {
				src_bits = (double *)FreeImage_GetScanLine(src, y);
				dst_bits = (FICOMPLEX *)FreeImage_GetScanLine(dst, y);
				for(x = 0; x < dst_width; x++) {
					dst_bits[x].i = src_bits[x];
				}
			}
			break;
	}

	return TRUE;
}
Example #27
0
static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
	FIBITMAP *dib = NULL;

	if(!handle) {
		return NULL;
	}

	BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;

	try {

		rgbeHeaderInfo header_info;
		unsigned width, height;

		// Read the header
		if(rgbe_ReadHeader(io, handle, &width, &height, &header_info) == FALSE) {
			return NULL;
		}

		// allocate a RGBF image
		dib = FreeImage_AllocateHeaderT(header_only, FIT_RGBF, width, height);
		if(!dib) {
			throw FI_MSG_ERROR_MEMORY;
		}

		// set the metadata as comments
		rgbe_ReadMetadata(dib, &header_info);

		if(header_only) {
			// header only mode
			return dib;
		}

		// read the image pixels and fill the dib
		
		for(unsigned y = 0; y < height; y++) {
			FIRGBF *scanline = (FIRGBF*)FreeImage_GetScanLine(dib, height - 1 - y);
			if(!rgbe_ReadPixels_RLE(io, handle, scanline, width, 1)) {
				FreeImage_Unload(dib);
				return NULL;
			}
		}

	}
	catch(const char *text) {
		if(dib != NULL) {
			FreeImage_Unload(dib);
		}
		FreeImage_OutputMessageProc(s_format_id, text);
	}

	return dib;
}
/** check and adapt scanline */
void Vt2IsoImageFreeImage_c::checkUpdateScanline( unsigned int aui_y )
{
 if ( i_curScanLineY != int(aui_y) )
 { // read scanline for given y
  // ( FreeImage library documentation states, that first scanline in memory is
  //   bottommost -> i.e. upsidedown in relation to other modellings
  //    -> change direction back to usual with ( ui_height - aui_y ) )
  scanline = FreeImage_GetScanLine(bitmap, ( (ui_height - 1) - aui_y ) );
  i_curScanLineY = aui_y;
 }
}
int DLL_CALLCONV
FIA_ReplaceColourPlanesHSV (FIBITMAP **src, FIBITMAP *H, FIBITMAP *S, FIBITMAP *V)
{
	// HSV source images must all be the same size
	FIBITMAP *R=NULL, *G=NULL, *B=NULL;
	int x, y;
	double h, s, v;

	// Check we have valid images
	if (!FreeImage_HasPixels(H) || !FIA_Is8Bit(H) ||
		!FreeImage_HasPixels(S) || !FIA_Is8Bit(S) ||
		!FreeImage_HasPixels(V) || !FIA_Is8Bit(V)) {
			return FIA_ERROR;
	}

	// alloc RGB to something the same size as the source images
	R = FreeImage_Clone(H);
	G = FreeImage_Clone(H);
	B = FreeImage_Clone(H);
 
	// Convert the HSV values to RGB and store
	for(y = 0; y < FreeImage_GetHeight(H); y++) {
		BYTE *src_h = FreeImage_GetScanLine(H, y);
		BYTE *src_s = FreeImage_GetScanLine(S, y);
		BYTE *src_v = FreeImage_GetScanLine(V, y);
		BYTE *dst_r = FreeImage_GetScanLine(R, y);
		BYTE *dst_g = FreeImage_GetScanLine(G, y);
		BYTE *dst_b = FreeImage_GetScanLine(B, y);
		
		for(x = 0; x < FreeImage_GetWidth(H); x++) {

			// Red, Green and Blue are between 0 and 255
			// Hue varies between 0 and 360
			// Satuation between 0 and 1
			// Value between 0 and 1

			h = ((double)(*src_h))/255.0 * 360.0;
			s = ((double)(*src_s))/255.0;
			v = ((double)(*src_v))/255.0;

			FIA_HSVToRGB (h, s, v, dst_r, dst_g, dst_b);

			// jump to next pixel
			src_h ++;
			src_s ++;
			src_v ++;
			dst_r ++;
			dst_g ++;
			dst_b ++;
		 }
	}

	FIA_ReplaceColourPlanes (src, R, G, B);

	FreeImage_Unload(R);
	FreeImage_Unload(G);
	FreeImage_Unload(B);

	return FIA_SUCCESS;
}
Example #30
0
/**
 * Clears the image to the chosen color. Returns 0 if there is no image loaded.
 * For ::IND_LUMINANCE image type, the 'color' value is taken from the pA parameter. Other parameters are ignored
 * @param pR						Byte R (Red).
 * @param pG						Byte G (Green).
 * @param pB						Byte B (Blue).
 * @param pA						Byte A (Transparency).
 */
bool IND_Image::clear(BYTE pR, BYTE pG, BYTE pB, BYTE pA) {
	// No image loaded
	if (!isImageLoaded() || !FreeImage_HasPixels(getFreeImageHandle())) 
		return false;

	FIBITMAP* dib = getFreeImageHandle();
	FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
	int bpp (getBpp());
	int bytespp = bpp/8;
	int colorFormat =  getFormatInt();

	//Interprets differently depending on image type
	switch(image_type) {
		case FIT_BITMAP:
			//LOOP - Y coords
			for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
				BYTE *bits = FreeImage_GetScanLine(dib, y);
				//LOOP - X coords
				for(unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
					// Set pixel color to total transparency, if color matches given colorkey
					
					//RGBx color format
					if(IND_COLOUR_INDEX != colorFormat && IND_LUMINANCE != colorFormat) {
						bits[FI_RGBA_RED] = pR;
						bits[FI_RGBA_GREEN] = pG;
						bits[FI_RGBA_BLUE] = pB;
					} else if (IND_COLOUR_INDEX == colorFormat) {
						//TODO
					} else if (IND_LUMINANCE == colorFormat) {
						assert (8 == bpp); //The bpp for IND_LUMINANCE should be 8 for this image type
						*bits = pA;
		}
					 
					if (IND_RGBA == colorFormat) {
						bits[FI_RGBA_ALPHA] = pA;
	}

					// jump to next pixel
					bits += bytespp;
				}//LOOP END
			}//LOOP END
		break;

		//TODO: OTHER IMAGE TYPES
		default:
		break;
	}
	return true;
}