/**
Extract the luminance channel L from a RGBF image. 
Luminance is calculated from the sRGB model (RGB2XYZ matrix) 
using a D65 white point : 
L = ( 0.2126 * r ) + ( 0.7152 * g ) + ( 0.0722 * b )
Reference : 
A Standard Default Color Space for the Internet - sRGB. 
[online] http://www.w3.org/Graphics/Color/sRGB
*/
FIBITMAP*  
ConvertRGBFToY(FIBITMAP *src) {
	if(FreeImage_GetImageType(src) != FIT_RGBF)
		return FALSE;

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

	FIBITMAP *dst = FreeImage_AllocateT(FIT_FLOAT, width, height);
	if(!dst) return NULL;

	unsigned src_pitch  = FreeImage_GetPitch(src);
	unsigned dst_pitch  = FreeImage_GetPitch(dst);

	
	BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
	BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);

	for(unsigned y = 0; y < height; y++) {
		const FIRGBF *src_pixel = (FIRGBF*)src_bits;
		float  *dst_pixel = (float*)dst_bits;
		for(unsigned x = 0; x < width; x++) {
			float L = 0.2126F * src_pixel[x].red + 0.7152F * src_pixel[x].green + 0.0722F * src_pixel[x].blue;
			dst_pixel[x] = (L > 0) ? L : 0;
		}
		// next line
		src_bits += src_pitch;
		dst_bits += dst_pitch;
	}

	return dst;
}
/**
Red-black Gauss-Seidel relaxation for model problem. Updates the current value of the solution
u[0..n-1][0..n-1], using the right-hand side function rhs[0..n-1][0..n-1].
*/
static void fmg_relaxation(FIBITMAP *U, FIBITMAP *RHS, int n) {
	int row, col, ipass, isw, jsw;
	const float h = 1.0F / (n - 1);
	const float h2 = h*h;

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

	for (ipass = 0, jsw = 1; ipass < 2; ipass++, jsw = 3-jsw) { // Red and black sweeps
		float *u_scan = u_bits + u_pitch;
		const float *rhs_scan = rhs_bits + rhs_pitch;
		for (row = 1, isw = jsw; row < n-1; row++, isw = 3-isw) {
			for (col = isw; col < n-1; col += 2) { 
				// Gauss-Seidel formula
				// calculate U(row, col) = 
				// 0.25 * [ U(row+1, col) + U(row-1, col) + U(row, col+1) + U(row, col-1) - h2 * RHS(row, col) ]		 
				float *u_center = u_scan + col;
				const float *rhs_center = rhs_scan + col;
				*u_center = *(u_center + u_pitch) + *(u_center - u_pitch) + *(u_center + 1) + *(u_center - 1);
				*u_center -= h2 * *rhs_center;
				*u_center *= 0.25F;
			}
			u_scan += u_pitch;
			rhs_scan += rhs_pitch;
		}
	}
}
示例#3
0
	///////////////////////////////////////////////////////////////////////////
	///
	/// @fn bool glLoadTexture(const std::string& nomFichier, unsigned int& idTexture,
	///                        bool genererTexture)
	///
	/// Cette fonction crée une texture OpenGL à partir d'une image contenu
	/// dans un fichier.  FreeImage est utilisée pour lire l'image, donc tous
	/// les formats reconnues par cette librairie devraient être supportés.
	///
	/// @param[in]  nomFichier     : Le nom du fichier image à charger.
	/// @param[out] idTexture      : L'identificateur de la texture créée.
	/// @param[in]  genererTexture : Doit-on demander à OpenGL de générer un numéro
	///										de texture au préalable?
	///
	/// @return Vrai si le chargement a réussi, faux autrement.
	///
	///////////////////////////////////////////////////////////////////////////
	bool glLoadTexture(const std::string& nomFichier, unsigned int& idTexture, bool genererTexture)
	{
		// Ce code de lecture générique d'un fichier provient de la
		// documentation de FreeImage
		FREE_IMAGE_FORMAT format = FIF_UNKNOWN;
		// check the file signature and deduce its format
		// (the second argument is currently not used by FreeImage)
		format = FreeImage_GetFileType(nomFichier.c_str(), 0);
		if(format == FIF_UNKNOWN) {
			// no signature ?
			// try to guess the file format from the file extension
			format = FreeImage_GetFIFFromFilename(nomFichier.c_str());
		}
		// check that the plugin has reading capabilities ...
		if((format == FIF_UNKNOWN) || !FreeImage_FIFSupportsReading(format)) {
			utilitaire::afficherErreur(
				std::string("Format du fichier image \"") +
				std::string(nomFichier.c_str()) + std::string("\" non supporté")
				);
			return false;
		}
		// ok, let's load the file
		FIBITMAP* dib = FreeImage_Load(format, nomFichier.c_str(), 0);

		if (dib == 0) {
			utilitaire::afficherErreur(
				std::string("Erreur à la lecture du fichier \"") +
				std::string(nomFichier.c_str()) + std::string("\"")
				);
			return false;
		}

		FIBITMAP* dib32 = FreeImage_ConvertTo32Bits(dib);
		if (dib32 == 0) {
			utilitaire::afficherErreur(
				std::string("Incapable de convertir le fichier \"") +
				std::string(nomFichier.c_str()) + std::string("\" en 32 bpp.")
				);
			FreeImage_Unload(dib);
			return false;
		}

		int pitch = FreeImage_GetPitch(dib32);

		glCreateTexture(
			FreeImage_GetBits(dib32),
			FreeImage_GetWidth(dib32),
			FreeImage_GetHeight(dib32),
			FreeImage_GetBPP(dib32),
			FreeImage_GetPitch(dib32),
			idTexture,
			genererTexture
			);

		FreeImage_Unload(dib32);
		FreeImage_Unload(dib);

		return true;
	}
示例#4
0
double ApplyCurve(FIBITMAP *src, FIBITMAP *dst, std::vector<cp> ctpts, int threadcount)
{
    _mark();
    unsigned spitch = FreeImage_GetPitch(src);
    unsigned dpitch = FreeImage_GetPitch(dst);
    unsigned w = FreeImage_GetWidth(src);
    unsigned h = FreeImage_GetHeight(src);
    BYTE * srcbits = FreeImage_GetBits(src);
    BYTE * dstbits = FreeImage_GetBits(dst);

    Curve c;
    BYTE LUT8[256];
    WORD LUT16[65536];
    c.setControlPoints(ctpts);
    int bpp = FreeImage_GetBPP(src);
    if (bpp == 24) {
        c.clampto(0.0,255.0);
        for (int x=0; x<256; x++) {
            LUT8[x] = (BYTE)floor(c.getpoint(x) + 0.5);
        }
        #pragma omp parallel for num_threads(threadcount)
        for(unsigned y = 0; y < h; y++) {
            for(unsigned x = 0; x < w; x++) {
                BYTE * bdstpix = (BYTE *) dstbits + dpitch*y + 3*x;
                BYTE *pixel = (BYTE *) (srcbits + spitch*y + 3*x);
                bdstpix[FI_RGBA_RED]   = LUT8[pixel[FI_RGBA_RED]];
                bdstpix[FI_RGBA_GREEN] = LUT8[pixel[FI_RGBA_GREEN]];
                bdstpix[FI_RGBA_BLUE]  = LUT8[pixel[FI_RGBA_BLUE]];

                //bdstpix[FI_RGBA_RED]   = ((BYTE *) LUT8)[pixel[FI_RGBA_RED]];
                //bdstpix[FI_RGBA_GREEN] = ((BYTE *) LUT8)[pixel[FI_RGBA_GREEN]];
                //bdstpix[FI_RGBA_BLUE]  = ((BYTE *) LUT8)[pixel[FI_RGBA_BLUE]];
            }
        }
    }
    if (bpp == 48) {
        c.scalepoints(256.0);
        c.clampto(0.0,65535.0);
        for (int x=0; x<65536; x++) {
            LUT16[x] = (WORD)floor(c.getpoint(x) + 0.5);
        }
        #pragma omp parallel for num_threads(threadcount)
        for(unsigned y = 0; y < h; y++) {
            for(unsigned x = 0; x < w; x++) {
                FIRGB16 * wdstpix = (FIRGB16 *) (dstbits + dpitch*y + 6*x);
                FIRGB16 * pixel   = (FIRGB16 *) (srcbits + spitch*y + 6*x);
                wdstpix->red   = LUT16[pixel->red];
                wdstpix->green = LUT16[pixel->green];
                wdstpix->blue  = LUT16[pixel->blue];

                //wdstpix->red   = ((WORD *) LUT16)[pixel->red];
                //wdstpix->green = ((WORD *) LUT16)[pixel->green];
                //wdstpix->blue  = ((WORD *) LUT16)[pixel->blue];
            }
        }
    }
    return _duration();
}
示例#5
0
double ApplyLUT(FIBITMAP *src, FIBITMAP *dst, char * LUT, int threadcount)
{
    _mark();
    unsigned spitch = FreeImage_GetPitch(src);
    unsigned dpitch = FreeImage_GetPitch(dst);
    unsigned w = FreeImage_GetWidth(src);
    unsigned h = FreeImage_GetHeight(src);
    BYTE * srcbits = FreeImage_GetBits(src);
    BYTE * dstbits = FreeImage_GetBits(dst);

    BYTE LUT8[256];
    WORD LUT16[65536];
    int bpp = FreeImage_GetBPP(src);
    if (bpp == 24) {
        for (int x=0; x<256; x++) {
            LUT8[x] = ((BYTE *) LUT)[x];;
        }
        #pragma omp parallel for num_threads(threadcount)
        for(unsigned y = 0; y < h; y++) {
            for(unsigned x = 0; x < w; x++) {
                BYTE * bdstpix = (BYTE *) (dstbits + dpitch*y + 3*x);
                BYTE * pixel   = (BYTE *) (srcbits + spitch*y + 3*x);
                bdstpix[FI_RGBA_RED]   = LUT8[pixel[FI_RGBA_RED]];
                bdstpix[FI_RGBA_GREEN] = LUT8[pixel[FI_RGBA_GREEN]];
                bdstpix[FI_RGBA_BLUE]  = LUT8[pixel[FI_RGBA_BLUE]];

                //bdstpix[FI_RGBA_RED]   = ((BYTE *) LUT8)[pixel[FI_RGBA_RED]];
                //bdstpix[FI_RGBA_GREEN] = ((BYTE *) LUT8)[pixel[FI_RGBA_GREEN]];
                //bdstpix[FI_RGBA_BLUE]  = ((BYTE *) LUT8)[pixel[FI_RGBA_BLUE]];


            }
        }
    }
    if (bpp == 48) {
        for (int x=0; x<65536; x++) {
            LUT16[x] = ((WORD *)LUT)[x];
        }
        #pragma omp parallel for num_threads(threadcount)
        for(unsigned y = 0; y < h-1; y++) {
            for(unsigned x = 0; x < w-1; x++) {
                FIRGB16 * wdstpix = (FIRGB16 *) (dstbits + dpitch*y + 6*x);
                FIRGB16 * pixel   = (FIRGB16 *) (srcbits + spitch*y + 6*x);
                wdstpix->red   = LUT16[pixel->red];
                wdstpix->green = LUT16[pixel->green];
                wdstpix->blue  = LUT16[pixel->blue];

                //wdstpix->red   = ((WORD *) LUT16)[pixel->red];
                //wdstpix->green = ((WORD *) LUT16)[pixel->green];
                //wdstpix->blue  = ((WORD *) LUT16)[pixel->blue];


            }
        }
    }
    return _duration();
}
示例#6
0
double ApplyLUT2LUMA(FIBITMAP *src, FIBITMAP *dst, char * LUT, int threadcount)
{
    _mark();
    unsigned spitch = FreeImage_GetPitch(src);
    unsigned dpitch = FreeImage_GetPitch(dst);
    unsigned w = FreeImage_GetWidth(src);
    unsigned h = FreeImage_GetHeight(src);
    BYTE * srcbits = FreeImage_GetBits(src);
    BYTE * dstbits = FreeImage_GetBits(dst);

    BYTE LUT8[256];
    WORD LUT16[65536];
    int bpp = FreeImage_GetBPP(src);
    if (bpp == 24) {
        for (int x=0; x<256; x++) {
            LUT8[x] = ((BYTE *) LUT)[x];
        }
        #pragma omp parallel for num_threads(threadcount)
        for(unsigned y = 0; y < h; y++) {
            for(unsigned x = 0; x < w; x++) {
                BYTE * bdstpix = (BYTE *) (dstbits + dpitch*y + 3*x);
                BYTE * pixel   = (BYTE *) (srcbits + spitch*y + 3*x);

                int lumaorig = (int) LUMA(pixel[FI_RGBA_RED],pixel[FI_RGBA_GREEN],pixel[FI_RGBA_BLUE]);
                int diff = lumaorig - LUT8[lumaorig];

                bdstpix[FI_RGBA_RED]   = std::min(std::max(bdstpix[FI_RGBA_RED] + diff,0),255);
                bdstpix[FI_RGBA_GREEN] = std::min(std::max(bdstpix[FI_RGBA_GREEN] + diff,0),255);
                bdstpix[FI_RGBA_BLUE]  = std::min(std::max(bdstpix[FI_RGBA_BLUE]  + diff,0),255);

            }
        }
    }
    if (bpp == 48) {
        for (int x=0; x<65536; x++) {
            LUT16[x] = ((WORD *)LUT)[x];
        }
        #pragma omp parallel for num_threads(threadcount)
        for(unsigned y = 0; y < h-1; y++) {
            for(unsigned x = 0; x < w-1; x++) {
                FIRGB16 * wdstpix = (FIRGB16 *) (dstbits + dpitch*y + 6*x);
                FIRGB16 * pixel   = (FIRGB16 *) (srcbits + spitch*y + 6*x);

                int lumaorig = (int) LUMA(pixel->red,pixel->green,pixel->blue);
                int diff = lumaorig - LUT16[lumaorig];

                wdstpix->red   = std::min(std::max(pixel->red + diff,0),65535);
                wdstpix->green = std::min(std::max(pixel->green + diff,0),65535);
                wdstpix->blue  = std::min(std::max(pixel->blue + diff,0),65535);

            }
        }
    }
    return _duration();
}
示例#7
0
double ApplyGray(FIBITMAP *src, FIBITMAP *dst, double redpct, double greenpct, double bluepct, int threadcount)
{
    _mark();

    int bpp = FreeImage_GetBPP(src);

    unsigned spitch = FreeImage_GetPitch(src);
    unsigned dpitch = FreeImage_GetPitch(dst);
    BYTE * srcbits = FreeImage_GetBits(src);
    BYTE * dstbits = FreeImage_GetBits(dst);


    switch(bpp) {
    case 48:
        #pragma omp parallel for num_threads(threadcount)
        for(unsigned y = 0; y < FreeImage_GetHeight(src); y++) {
            for(unsigned x = 0; x < FreeImage_GetWidth(src); x++) {
                FIRGB16 * wdstpix = (FIRGB16 *) (dstbits + dpitch*y + 6*x);
                FIRGB16 * pixel   = (FIRGB16 *) (srcbits + spitch*y + 6*x);

                double G = floor((double) pixel->red*redpct + (double) pixel->green*greenpct + (double) pixel->blue*bluepct)+0.5;
                if (G>65535.0) G=65535.0;
                if (G<0.0) G=0.0;

                wdstpix->red = int(G);
                wdstpix->green = int(G);
                wdstpix->blue = int(G);
            }
        }
        break;
    case 24 :
        #pragma omp parallel for num_threads(threadcount)
        for(unsigned y = 0; y < FreeImage_GetHeight(src); y++) {
            for(unsigned x = 0; x < FreeImage_GetWidth(src); x++) {
                BYTE * bdstpix = (BYTE *) dstbits + dpitch*y + 3*x;
                BYTE *pixel = (BYTE *) (srcbits + spitch*y + 3*x);

                double G = floor((double) pixel[FI_RGBA_RED]*redpct + (double) pixel[FI_RGBA_GREEN]*greenpct + (double) pixel[FI_RGBA_BLUE]*bluepct)+0.5;
                if (G>255.0) G=255.0;
                if (G<0.0) G=0.0;

                bdstpix[FI_RGBA_RED] = int(G);
                bdstpix[FI_RGBA_GREEN] = int(G);
                bdstpix[FI_RGBA_BLUE]= int(G);

            }
        }
        break;
    }
    return _duration();

}
示例#8
0
std::ostream &
operator <<(std::ostream &rOutputStream, const FIBITMAP &rBitmap)
{
    unsigned int nImageWidth    = FreeImage_GetWidth(const_cast<FIBITMAP *>(&rBitmap));
    unsigned int nImageHeight   = FreeImage_GetHeight(const_cast<FIBITMAP *>(&rBitmap));
    unsigned int nPitch         = FreeImage_GetPitch(const_cast<FIBITMAP *>(&rBitmap));
    unsigned int nBPP           = FreeImage_GetBPP(const_cast<FIBITMAP *>(&rBitmap));

    FREE_IMAGE_COLOR_TYPE eType = FreeImage_GetColorType(const_cast<FIBITMAP *>(&rBitmap));
    BITMAPINFO *pInfo          = FreeImage_GetInfo(const_cast<FIBITMAP *>(&rBitmap));

    rOutputStream << "Size  (" << FreeImage_GetWidth(const_cast<FIBITMAP *>(&rBitmap)) << ", "
                  << FreeImage_GetHeight(const_cast<FIBITMAP *>(&rBitmap)) << ")\n";
    rOutputStream << "Pitch "  << FreeImage_GetPitch(const_cast<FIBITMAP *>(&rBitmap)) << "\n";
    rOutputStream << "Type  ";

    switch (eType)
    {
        case FIC_MINISWHITE:
            rOutputStream << "FIC_MINISWHITE\n";
            break;

        case FIC_MINISBLACK:
            rOutputStream << "FIC_MINISBLACK\n";
            break;

        case FIC_RGB:
            rOutputStream << "FIC_RGB\n";
            break;

        case FIC_PALETTE:
            rOutputStream << "FIC_PALETTE\n";
            break;

        case FIC_RGBALPHA:
            rOutputStream << "FIC_RGBALPHA\n";
            break;

        case FIC_CMYK:
            rOutputStream << "FIC_CMYK\n";
            break;

        default:
            rOutputStream << "Unknown pixel format.\n";
    }

    rOutputStream << "BPP   " << nBPP << std::endl;

    return rOutputStream;
}
/**
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;
		}
	}
}
示例#10
0
void ImageLoader::
compatible()
{
	// BITMAP数据是从下往上的, 需要翻转
	FreeImage_FlipVertical(mDIB);

	// FreeImage是BGR顺序, 与NVTT要求的一致, 而PVRT需要RGB顺序, 两者都需要32bits数据
	if (config.imageCompressionType != CT_DXTC)
	{
		// 将BGR改为RGB, 交换R channel和B channel
		const unsigned bytesperpixel = FreeImage_GetBPP(mDIB) / 8;
		const unsigned height = FreeImage_GetHeight(mDIB);
		const unsigned pitch = FreeImage_GetPitch(mDIB);
		const unsigned lineSize = FreeImage_GetLine(mDIB);

		BYTE* line = FreeImage_GetBits(mDIB);
		for (unsigned y = 0; y < height; ++y, line += pitch) {
			for (BYTE* pixel = line; pixel < line + lineSize; pixel += bytesperpixel) {
				INPLACESWAP(pixel[0], pixel[2]);
			}
		}
	}

	if (FreeImage_GetBPP(mDIB) != 32)
	{
		FIBITMAP* convertDIB = FreeImage_ConvertTo32Bits(mDIB);
		FreeImage_Unload(mDIB);
		mDIB = convertDIB;
	}
}
示例#11
0
FIBITMAP * CreateTemplete(FIBITMAP * hImage, unsigned ScreenWidth, unsigned ScreenHeight) // 创建空白PNG模版
{
	FIBITMAP * hPicTemplete;
	RGBQUAD * palMain ;
	RGBQUAD * palTemplete ;
	unsigned ImgPitchLocal ;
	BYTE * pBitLocal;
	unsigned x, y, n;

	hPicTemplete = FreeImage_Allocate(ScreenWidth, ScreenHeight, 8, 0, 0, 0);  //创建目标图像
	palMain = FreeImage_GetPalette(hImage);
	palTemplete = FreeImage_GetPalette(hPicTemplete);
	for (n = 0 ; n < 256 ; n++) {
		palTemplete[n].rgbRed = palMain[n].rgbRed ;
		palTemplete[n].rgbGreen = palMain[n].rgbGreen ;
		palTemplete[n].rgbBlue = palMain[n].rgbBlue ;
	}
	palTemplete[70].rgbRed = 255   ;
	palTemplete[70].rgbGreen = 255 ;
	palTemplete[70].rgbBlue = 255  ;
//	FreeImage_SetTransparent(hPicTemplete, false);
	// 所有像素颜色填充为 70 号索引
	ImgPitchLocal = FreeImage_GetPitch(hPicTemplete) ;
	pBitLocal = FreeImage_GetBits(hPicTemplete);
	for (y = 0 ; y < ScreenHeight; y++) {
		for (x = 0; x < ScreenWidth ; x++)
			pBitLocal[x] = 70 ;
		pBitLocal += ImgPitchLocal ; // 下一行
	}
	return hPicTemplete;
}
示例#12
0
Image *Image::New(FIBITMAP* dib) {
  NanScope();

  Local<Value> arg = NanNew<Integer>(0);
  Local<Object> obj = NanNew<FunctionTemplate>(constructor_template)->GetFunction()->NewInstance(1, &arg);

  Image *image = ObjectWrap::Unwrap<Image>(obj);

  int w,h,pitch;
  FREE_IMAGE_TYPE type = FreeImage_GetImageType(dib);

  obj->SetInternalField(0, NanNew<External>(dib));
  obj->Set(NanNew<String>("width"), NanNew<Integer>(w=FreeImage_GetWidth(dib)));
  obj->Set(NanNew<String>("height"), NanNew<Integer>(h=FreeImage_GetHeight(dib)));
  obj->Set(NanNew<String>("bpp"), NanNew<Integer>((int)FreeImage_GetBPP(dib)));
  obj->Set(NanNew<String>("pitch"), NanNew<Integer>(pitch=FreeImage_GetPitch(dib)));
  obj->Set(NanNew<String>("type"), NanNew<Integer>(type));
  obj->Set(NanNew<String>("redMask"), NanNew<Integer>((int)FreeImage_GetRedMask(dib)));
  obj->Set(NanNew<String>("greenMask"), NanNew<Integer>((int)FreeImage_GetGreenMask(dib)));
  obj->Set(NanNew<String>("blueMask"), NanNew<Integer>((int)FreeImage_GetBlueMask(dib)));

  BYTE *bits = FreeImage_GetBits(dib);
  obj->Set(NanNew<String>("buffer"), NanNewBufferHandle((char*) bits, h * pitch));

  return image;
}
示例#13
0
void
FreeImageStack::loadImage(unsigned int iSlice, npp::ImageNPP_8u_C1 & rImage)
const
{
    NPP_ASSERT_MSG(iSlice < slices(), "Slice index exceeded number of slices in stack.");
    FIBITMAP * pBitmap = FreeImage_LockPage(pImageStack_, iSlice);
    NPP_ASSERT_NOT_NULL(pBitmap);
            // make sure this is an 8-bit single channel image
    NPP_DEBUG_ASSERT(FreeImage_GetColorType(pBitmap) == FIC_MINISBLACK);
    NPP_DEBUG_ASSERT(FreeImage_GetBPP(pBitmap) == 8);
    
    NPP_DEBUG_ASSERT(FreeImage_GetWidth(pBitmap) == nWidth_);
    NPP_DEBUG_ASSERT(FreeImage_GetHeight(pBitmap) == nHeight_);
    unsigned int    nSrcPitch = FreeImage_GetPitch(pBitmap);
    unsigned char * pSrcData  = FreeImage_GetBits(pBitmap);
    
    if (rImage.width() == nWidth_ && rImage.height() == nHeight_)
    {
        NPP_CHECK_CUDA(cudaMemcpy2D(rImage.data(), rImage.pitch(), pSrcData, nSrcPitch, 
                                    nWidth_, nHeight_, cudaMemcpyHostToDevice));
    }
    else
    {
                // create new NPP image
        npp::ImageNPP_8u_C1 oImage(nWidth_, nHeight_);
                // transfer slice data into new device image
        NPP_CHECK_CUDA(cudaMemcpy2D(oImage.data(), oImage.pitch(), pSrcData, nSrcPitch, 
                                    nWidth_, nHeight_, cudaMemcpyHostToDevice));
                // swap the result image with the reference passed into this method
        rImage.swap(oImage);
    }
                // release locked slice
    FreeImage_UnlockPage(pImageStack_, pBitmap, FALSE);
}
示例#14
0
	FreeImage::FreeImage( const FreeImage & freeImage, const Math::Vec2<Size> & newSize, Filter resampleFilter ) :
		BasicLoadable( freeImage ),
		fileName( freeImage.fileName ),
		#ifdef WIN32
		fileNameW( freeImage.fileNameW ),
		#endif
		size( newSize ),
		invertY( freeImage.invertY ),
		loadingType( freeImage.loadingType ),
		BPP( freeImage.BPP ),
		loadingFormat( freeImage.loadingFormat ),
		resampleFilter( resampleFilter ) {
		if ( freeImage.isLoaded() ) {
			Math::Vec2<Size> toCopySize = freeImage.getSize();

			if ( this -> size != toCopySize )
				this -> freeImage = FreeImage_Rescale( freeImage.freeImage, this -> size.x, this -> size.y, ( FREE_IMAGE_FILTER ) this -> resampleFilter );
			else
				this -> freeImage = FreeImage_Clone( freeImage.freeImage );
		} else {
			this -> freeImage = freeImage.freeImage;	//Probably NULL
		}
		if ( this -> freeImage )
			this -> stride = FreeImage_GetPitch( this -> freeImage );
		else
			this -> stride = 0;
	}
示例#15
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);
	}
}
/**
Get the maximum, minimum and average luminance
@param dib Source Y image to analyze
@param maxLum Maximum luminance
@param minLum Minimum luminance
@param worldLum Average luminance (world adaptation luminance)
@return Returns TRUE if successful, returns FALSE otherwise
@see ConvertRGBFToY
*/
BOOL 
LuminanceFromY(FIBITMAP *dib, float *maxLum, float *minLum, float *worldLum) {
	if(FreeImage_GetImageType(dib) != FIT_FLOAT)
		return FALSE;

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

	float max_lum = -1e20F, min_lum = 1e20F;
	double sum = 0;

	BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
	for(unsigned y = 0; y < height; y++) {
		const float *pixel = (float*)bits;
		for(unsigned x = 0; x < width; x++) {
			const float Y = pixel[x];
			max_lum = (max_lum < Y) ? Y : max_lum;				// max Luminance in the scene
			min_lum = ((Y > 0) && (min_lum < Y)) ? min_lum : Y;	// min Luminance in the scene
			sum += log(2.3e-5 + Y);								// contrast constant in Tumblin paper
		}
		// next line
		bits += pitch;
	}
	// maximum luminance
	*maxLum = max_lum;
	// minimum luminance
	*minLum = min_lum;
	// average log luminance
	double avgLogLum = (sum / (width * height));
	// world adaptation luminance
	*worldLum = (float)exp(avgLogLum);

	return TRUE;
}
FIBITMAP* getBmpFromPixels(ofPixels_<PixelType> &pix){
	PixelType* pixels = pix.getPixels();
	unsigned int width = pix.getWidth();
	unsigned int height = pix.getHeight();
	unsigned int bpp = pix.getBitsPerPixel();
	
	FREE_IMAGE_TYPE freeImageType = getFreeImageType(pix);
	FIBITMAP* bmp = FreeImage_AllocateT(freeImageType, width, height, bpp);
	unsigned char* bmpBits = FreeImage_GetBits(bmp);
	if(bmpBits != NULL) {
		int srcStride = width * pix.getBytesPerPixel();
		int dstStride = FreeImage_GetPitch(bmp);
		unsigned char* src = (unsigned char*) pixels;
		unsigned char* dst = bmpBits;
		for(int i = 0; i < (int)height; i++) {
			memcpy(dst, src, dstStride);
			src += srcStride;
			dst += dstStride;
		}
	} else {
		ofLogError() << "ofImage::getBmpFromPixels() unable to get FIBITMAP from ofPixels";
	}
	
	// ofPixels are top left, FIBITMAP is bottom left
	FreeImage_FlipVertical(bmp);
	
	return bmp;
}
示例#18
0
Image *Image::New(FIBITMAP* dib) {

  HandleScope scope;

  Local<Value> arg = Integer::NewFromUnsigned(0);
  Local<Object> obj = constructor_template->GetFunction()->NewInstance(1, &arg);

  Image *image = ObjectWrap::Unwrap<Image>(obj);
  image->dib = dib;

  int w,h,pitch;
  FREE_IMAGE_TYPE type = FreeImage_GetImageType(dib);

  obj->SetInternalField(0, External::New(dib));
  obj->Set(JS_STR("width"), JS_INT(w=FreeImage_GetWidth(dib)));
  obj->Set(JS_STR("height"), JS_INT(h=FreeImage_GetHeight(dib)));
  obj->Set(JS_STR("bpp"), JS_INT((int)FreeImage_GetBPP(dib)));
  obj->Set(JS_STR("pitch"), JS_INT(pitch=FreeImage_GetPitch(dib)));
  obj->Set(JS_STR("type"), JS_INT(type));
  obj->Set(JS_STR("redMask"), JS_INT((int)FreeImage_GetRedMask(dib)));
  obj->Set(JS_STR("greenMask"), JS_INT((int)FreeImage_GetGreenMask(dib)));
  obj->Set(JS_STR("blueMask"), JS_INT((int)FreeImage_GetBlueMask(dib)));

  BYTE *bits=FreeImage_GetBits(dib);
  node::Buffer *buf = node::Buffer::New((char*)bits,h*pitch);
  obj->Set(JS_STR("buffer"), buf->handle_);

  return image;
}
示例#19
0
/**
Get the maximum, minimum and average luminance.<br>
On input, pixel->red == Y, pixel->green == x, pixel->blue == y
@param Yxy Source Yxy image to analyze
@param maxLum Maximum luminance
@param minLum Minimum luminance
@param worldLum Average luminance (world adaptation luminance)
@return Returns TRUE if successful, returns FALSE otherwise
*/
BOOL 
LuminanceFromYxy(FIBITMAP *Yxy, float *maxLum, float *minLum, float *worldLum) {
	if(FreeImage_GetImageType(Yxy) != FIT_RGBF)
		return FALSE;

	const unsigned width  = FreeImage_GetWidth(Yxy);
	const unsigned height = FreeImage_GetHeight(Yxy);
	const unsigned pitch  = FreeImage_GetPitch(Yxy);

	float max_lum = 0, min_lum = 0;
	double sum = 0;

	BYTE *bits = (BYTE*)FreeImage_GetBits(Yxy);
	for(unsigned y = 0; y < height; y++) {
		const FIRGBF *pixel = (FIRGBF*)bits;
		for(unsigned x = 0; x < width; x++) {
			const float Y = MAX(0.0F, pixel[x].red);// avoid negative values
			max_lum = (max_lum < Y) ? Y : max_lum;	// max Luminance in the scene
			min_lum = (min_lum < Y) ? min_lum : Y;	// min Luminance in the scene
			sum += log(2.3e-5F + Y);				// contrast constant in Tumblin paper
		}
		// next line
		bits += pitch;
	}
	// maximum luminance
	*maxLum = max_lum;
	// minimum luminance
	*minLum = min_lum;
	// average log luminance
	double avgLogLum = (sum / (width * height));
	// world adaptation luminance
	*worldLum = (float)exp(avgLogLum);

	return TRUE;
}
示例#20
0
/**
Custom gamma correction based on the ITU-R BT.709 standard
@param dib RGBF image to be corrected
@param gammaval Gamma value (2.2 is a good default value)
@return Returns TRUE if successful, returns FALSE otherwise
*/
static BOOL 
REC709GammaCorrection(FIBITMAP *dib, const float gammaval) {
	if(FreeImage_GetImageType(dib) != FIT_RGBF)
		return FALSE;

	float slope = 4.5F;
	float start = 0.018F;
	
	const float fgamma = (float)((0.45 / gammaval) * 2);
	if(gammaval >= 2.1F) {
		start = (float)(0.018 / ((gammaval - 2) * 7.5));
		slope = (float)(4.5 * ((gammaval - 2) * 7.5));
	} else if (gammaval <= 1.9F) {
		start = (float)(0.018 * ((2 - gammaval) * 7.5));
		slope = (float)(4.5 / ((2 - gammaval) * 7.5));
	}

	const unsigned width  = FreeImage_GetWidth(dib);
	const unsigned height = FreeImage_GetHeight(dib);
	const unsigned pitch  = FreeImage_GetPitch(dib);

	BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
	for(unsigned y = 0; y < height; y++) {
		float *pixel = (float*)bits;
		for(unsigned x = 0; x < width; x++) {
			for(int i = 0; i < 3; i++) {
				*pixel = (*pixel <= start) ? *pixel * slope : (1.099F * pow(*pixel, fgamma) - 0.099F);
				pixel++;
			}
		}
		bits += pitch;
	}

	return TRUE;
}
示例#21
0
	FreeImage & FreeImage::operator=( const FreeImage & image ) {
		this -> fileName = image.fileName;
		#ifdef WIN32
		this -> fileNameW = image.fileNameW;
		#endif
		this -> size = size;
		this -> invertY = image.invertY;
		this -> loadingType = image.loadingType;
		this -> BPP = image.BPP;
		this -> loadingFormat = image.loadingFormat;
		this -> resampleFilter = image.resampleFilter;

		if ( image.isLoaded() ) {
			lock();
			this -> freeImage = FreeImage_Clone( image.freeImage );
			setLoaded( true );
			unlock();
		} else {
			this -> freeImage = image.freeImage;	//Probably NULL
			setLoaded( false );
		}
		if ( this -> freeImage )
			this -> stride = FreeImage_GetPitch( this -> freeImage );
		else
			this -> stride = 0;

		return *this;
	}
示例#22
0
	void FreeImage::loadFromDatas( unsigned char * datas, const Math::Vec2<Size> & size, Format format, bool datasInvertY ) {
		unload();

		lock();
		setLoading( true );
		_updateFormat( format );
		this -> size = size;
		this -> invertY = datasInvertY;
		this -> loadingType = LoadingType::EMPTY;
		this -> fileName.clear();			//we have no reason to keep a filepath now.
		#ifdef WIN32
		this -> fileNameW.clear();			//we have no reason to keep a filepath now.
		#endif // WIN32

		#ifdef WIN32 
		if ( format == Format::RGB || format == Format::RGBA ) {
			//because FreeImage do not care of MASK and use BGR on Windows
			size_t numPixels = this -> size.x * this -> size.y;
			size_t offsetPerPixel = ( this -> BPP / 8 );
			unsigned char * newDatas = new unsigned char[offsetPerPixel * numPixels];

			auto otherIt = datas;
			auto thisIt = newDatas;

			if ( format == Format::RGB ) {
				for ( size_t i = 0; i < numPixels; i++ ) {
					thisIt[0] = otherIt[2];
					thisIt[1] = otherIt[1];
					thisIt[2] = otherIt[0];

					otherIt += offsetPerPixel;
					thisIt += offsetPerPixel;
				}
			} else if ( format == Format::RGBA ) {
				for ( size_t i = 0; i < numPixels; i++ ) {
					thisIt[0] = otherIt[2];
					thisIt[1] = otherIt[1];
					thisIt[2] = otherIt[0];
					thisIt[3] = otherIt[3];

					otherIt += offsetPerPixel;
					thisIt += offsetPerPixel;
				}
			}
			
			this -> freeImage = FreeImage_ConvertFromRawBits( newDatas, this -> size.x, this -> size.y, this -> size.x * ( this -> BPP / 8 ), this -> BPP, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, this -> invertY );
			delete[] newDatas;
		} else {
			this -> freeImage = FreeImage_ConvertFromRawBits( datas, this -> size.x, this -> size.y, this -> size.x * ( this -> BPP / 8 ), this -> BPP, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, this -> invertY );
		}
		#else
		this -> freeImage = FreeImage_ConvertFromRawBits( datas, this -> size.x, this -> size.y, this -> size.x * ( this -> BPP / 8 ), this -> BPP, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, this -> invertY );
		#endif

		this -> stride = FreeImage_GetPitch( this -> freeImage );

		setLoading( false );
		setLoaded( true );
		unlock();
	}
/**
Coarse-to-fine prolongation by bilinear interpolation. nf is the fine-grid dimension. The coarsegrid
solution is input as uc[0..nc-1][0..nc-1], where nc = nf/2 + 1. The fine-grid solution is
returned in uf[0..nf-1][0..nf-1].
*/
static void fmg_prolongate(FIBITMAP *UF, FIBITMAP *UC, int nf) {
	int row_uc, row_uf, col_uc, col_uf;

	const int uf_pitch  = FreeImage_GetPitch(UF) / sizeof(float);
	const int uc_pitch  = FreeImage_GetPitch(UC) / sizeof(float);
	
	float *uf_bits = (float*)FreeImage_GetBits(UF);
	const float *uc_bits = (float*)FreeImage_GetBits(UC);
	
	// do elements that are copies
	{
		const int nc = nf/2 + 1;

		float *uf_scan = uf_bits;
		const float *uc_scan = uc_bits;		
		for (row_uc = 0; row_uc < nc; row_uc++) {
			for (col_uc = 0, col_uf = 0; col_uc < nc; col_uc++, col_uf += 2) {
				// calculate UF(2*row_uc, col_uf) = UC(row_uc, col_uc);
				uf_scan[col_uf] = uc_scan[col_uc];
			}
			uc_scan += uc_pitch;
			uf_scan += 2 * uf_pitch;
		}
	}
	// do odd-numbered columns, interpolating vertically
	{		
		for(row_uf = 1; row_uf < nf-1; row_uf += 2) {
			float *uf_scan = uf_bits + row_uf * uf_pitch;
			for (col_uf = 0; col_uf < nf; col_uf += 2) {
				// calculate UF(row_uf, col_uf) = 0.5 * ( UF(row_uf+1, col_uf) + UF(row_uf-1, col_uf) )
				uf_scan[col_uf] = 0.5F * ( *(uf_scan + uf_pitch + col_uf) + *(uf_scan - uf_pitch + col_uf) );
			}
		}
	}
	// do even-numbered columns, interpolating horizontally
	{
		float *uf_scan = uf_bits;
		for(row_uf = 0; row_uf < nf; row_uf++) {
			for (col_uf = 1; col_uf < nf-1; col_uf += 2) {
				// calculate UF(row_uf, col_uf) = 0.5 * ( UF(row_uf, col_uf+1) + UF(row_uf, col_uf-1) )
				uf_scan[col_uf] = 0.5F * ( uf_scan[col_uf + 1] + uf_scan[col_uf - 1] );
			}
			uf_scan += uf_pitch;
		}
	}
}
/**
Does coarse-to-fine interpolation and adds result to uf. nf is the fine-grid dimension. The
coarse-grid solution is input as uc[0..nc-1][0..nc-1], where nc = nf/2+1. The fine-grid solution
is returned in uf[0..nf-1][0..nf-1]. res[0..nf-1][0..nf-1] is used for temporary storage.
*/
static void fmg_addint(FIBITMAP *UF, FIBITMAP *UC, FIBITMAP *RES, int nf) {
	fmg_prolongate(RES, UC, nf);

	const int uf_pitch  = FreeImage_GetPitch(UF) / sizeof(float);
	const int res_pitch  = FreeImage_GetPitch(RES) / sizeof(float);	

	float *uf_bits = (float*)FreeImage_GetBits(UF);
	const float *res_bits = (float*)FreeImage_GetBits(RES);

	for(int row = 0; row < nf; row++) {
		for(int col = 0; col < nf; col++) {
			// calculate UF(row, col) = UF(row, col) + RES(row, col);
			uf_bits[col] += res_bits[col];
		}
		uf_bits += uf_pitch;
		res_bits += res_pitch;
	}
}
示例#25
0
bool tpImageIO::readHDR(tpImageColorHDR& I, const char* path)
{

	FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(path, 0);
	
	if(fifmt == FIF_UNKNOWN)
	{
		std::cerr << "[Error] tpImageIO : Unknow type !" << std::endl; 
		//TODO: Exceptions ?
		return false;
	}
	
	

	FIBITMAP *dib = FreeImage_Load(fifmt, path,0);
    
	if( dib == NULL )
	{
		std::cerr << "[Error] tpImageIO : Impossible d'ouvrir l'image : " << path << std::endl;
		// TODO: Exceptions ?
		return false;
	}

	if(FreeImage_GetImageType(dib)!=FIT_RGBF)
	{
		std::cerr << "[Error] tpImageIO : Unknow type !" << std::endl; 
		//TODO: Exceptions ?
		return false;
	}

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

	I.resize(height,width);

	FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
	// test pixel access avoiding scanline calculations
	// to speed-up the image processing
	if(image_type == FIT_RGBF) {
		BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
		for(int y = 0; y < height; y++) {
		FIRGBF *pixel = (FIRGBF*)bits;
		for(int x = 0; x < width; x++) {
		I[y][x].r = pixel[x].red;
		I[y][x].g = pixel[x].green;
		I[y][x].b = pixel[x].blue;
		}
		// next line
		bits += pitch;
		}
	}

	FreeImage_Unload(dib);

	return true;
}
示例#26
0
HANDLE fipWinImage::copyToHandle() const {
	HANDLE hMem = NULL;

	if(_dib) {

		// Get equivalent DIB size
		long dib_size = sizeof(BITMAPINFOHEADER);
		dib_size += FreeImage_GetColorsUsed(_dib) * sizeof(RGBQUAD);
		dib_size += FreeImage_GetPitch(_dib) * FreeImage_GetHeight(_dib);

		// Allocate a DIB
		hMem = GlobalAlloc(GHND, dib_size);
		BYTE *dib = (BYTE*)GlobalLock(hMem);

		memset(dib, 0, dib_size);

		BYTE *p_dib = (BYTE*)dib;

		// Copy the BITMAPINFOHEADER

		BITMAPINFOHEADER *bih = FreeImage_GetInfoHeader(_dib);
		memcpy(p_dib, bih, sizeof(BITMAPINFOHEADER));
		if(FreeImage_GetImageType(_dib) != FIT_BITMAP) {
			// this hack is used to store the bitmap type in the biCompression member of the BITMAPINFOHEADER
			SET_FREEIMAGE_MARKER((BITMAPINFOHEADER*)p_dib, _dib);
		}
		p_dib += sizeof(BITMAPINFOHEADER);

		// Copy the palette

		RGBQUAD *pal = FreeImage_GetPalette(_dib);
		memcpy(p_dib, pal, FreeImage_GetColorsUsed(_dib) * sizeof(RGBQUAD));
		p_dib += FreeImage_GetColorsUsed(_dib) * sizeof(RGBQUAD);

		// Copy the bitmap

		BYTE *bits = FreeImage_GetBits(_dib);
		memcpy(p_dib, bits, FreeImage_GetPitch(_dib) * FreeImage_GetHeight(_dib));

		GlobalUnlock(hMem);
	}

	return hMem;
}
示例#27
0
		bool Image::load(const char* filename)
		{
			const uint32_t argb_r = 0xFF000000u;
			const uint32_t argb_g = 0x00FF0000u;
			const uint32_t argb_b = 0x0000FF00u;
			const uint32_t argb_a = 0x000000FFu;

			FREE_IMAGE_FORMAT format;
			FIBITMAP* bitmap;
			FIBITMAP* rgbamap;
			int32_t w, h;

			// Unload if image already loaded to protect from memory leak
			unload();

			// Get filetype
			format = FreeImage_GetFileType(filename);

			if (format == FIF_UNKNOWN)
			{
				fprintf(stderr, "Failed to ascertain filetype of %s\n",
					filename);
				return false;
			}

			// Load image
			bitmap = FreeImage_Load(format, filename);

			if (bitmap == nullptr)
			{
				fprintf(stderr, "Failed to load %s\n", filename);
				return false;
			}

			// Get width and height
			w = FreeImage_GetWidth(bitmap);
			h = FreeImage_GetHeight(bitmap);

			// Convert to RGBA if not already
			rgbamap = FreeImage_ConvertTo32Bits(bitmap);
			int32_t scan_width = FreeImage_GetPitch(rgbamap);

			// Make copy
			int32_t size = h * scan_width;
			_pixels = malloc(size);
			FreeImage_ConvertToRawBits((BYTE*)_pixels, bitmap, scan_width, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, true);

			_width = w;
			_height = h;

			// Unload FreeImage bitmaps
			FreeImage_Unload(bitmap);
			FreeImage_Unload(rgbamap);

			return true;
		}
示例#28
0
// Takes an image from the frame buffer and compresses it
int writeFrame(FIMEMORY *fiBuffer, FIBITMAP *fiImage, unsigned char imageType) {
	/*
	char msg[1024];
	sprintf_s(msg, 1024, "imageType: %i", imageType);
	MessageBox(NULL,msg,"ADES DEBUG", MB_OK);
	*/
	imageType = 2;
	int errStatus = 1;
	u_short imageWidth, imageHeight;

	unsigned width, height, pitch, line;
	BYTE *bits;

	// Package image using correct compression
	switch(imageType) {
	case 0: // Send a raw frame
		// Get image characteristics
		width = FreeImage_GetWidth(fiImage);
		height = FreeImage_GetHeight(fiImage);
		pitch = FreeImage_GetPitch(fiImage);
		line = FreeImage_GetLine(fiImage);

		// Write out width and height
		errStatus = FreeImage_SeekMemory(fiBuffer, 0, SEEK_SET);
		if (errStatus != 1) break;

		imageWidth = htons(width);
		errStatus = FreeImage_WriteMemory( &imageWidth, 2, 1, fiBuffer );
		if (errStatus != 1) break;
		
		imageHeight = htons(height);
		errStatus = FreeImage_WriteMemory( &imageHeight, 2, 1, fiBuffer );
		if (errStatus != 1) break;

		// Write out image (convert the bitmap to raw bits, top-left pixel first)
		bits = (BYTE*)malloc(height * pitch);
		FreeImage_ConvertToRawBits(bits, fiImage, pitch, 24, 
			FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE);
		errStatus = FreeImage_WriteMemory( bits, height*pitch*sizeof(BYTE), 1, fiBuffer );
		free(bits);
		if (errStatus != 1) break;
		
		break;
	default: // Send a jpg frame
		errStatus = FreeImage_SeekMemory(fiBuffer, 0, SEEK_SET);
		if (errStatus != 1) break;

		errStatus = FreeImage_SaveToMemory(FIF_JPEG, fiImage, fiBuffer, convertToJpegFlag(imageType));
		if (errStatus != 1) break;
		break;
	}
	
	// Clean up and exit
	return errStatus;
}
示例#29
0
void putBmpIntoPixels(FIBITMAP * bmp, ofPixels_<PixelType> &pix, bool swapForLittleEndian = true) {
	// convert to correct type depending on type of input bmp and PixelType
	FIBITMAP* bmpConverted = NULL;
	FREE_IMAGE_TYPE imgType = FreeImage_GetImageType(bmp);
	if(sizeof(PixelType)==1 &&
		(FreeImage_GetColorType(bmp) == FIC_PALETTE || FreeImage_GetBPP(bmp) < 8
		||  imgType!=FIT_BITMAP)) {
		if(FreeImage_IsTransparent(bmp)) {
			bmpConverted = FreeImage_ConvertTo32Bits(bmp);
		} else {
			bmpConverted = FreeImage_ConvertTo24Bits(bmp);
		}
		bmp = bmpConverted;
	}else if(sizeof(PixelType)==2 && imgType!=FIT_UINT16 && imgType!=FIT_RGB16 && imgType!=FIT_RGBA16){
		if(FreeImage_IsTransparent(bmp)) {
			bmpConverted = FreeImage_ConvertToType(bmp,FIT_RGBA16);
		} else {
			bmpConverted = FreeImage_ConvertToType(bmp,FIT_RGB16);
		}
		bmp = bmpConverted;
	}else if(sizeof(PixelType)==4 && imgType!=FIT_FLOAT && imgType!=FIT_RGBF && imgType!=FIT_RGBAF){
		if(FreeImage_IsTransparent(bmp)) {
			bmpConverted = FreeImage_ConvertToType(bmp,FIT_RGBAF);
		} else {
			bmpConverted = FreeImage_ConvertToType(bmp,FIT_RGBF);
		}
		bmp = bmpConverted;
	}

	unsigned int width = FreeImage_GetWidth(bmp);
	unsigned int height = FreeImage_GetHeight(bmp);
	unsigned int bpp = FreeImage_GetBPP(bmp);
	unsigned int channels = (bpp / sizeof(PixelType)) / 8;
	unsigned int pitch = FreeImage_GetPitch(bmp);

	// ofPixels are top left, FIBITMAP is bottom left
	FreeImage_FlipVertical(bmp);
	
	unsigned char* bmpBits = FreeImage_GetBits(bmp);
	if(bmpBits != NULL) {
		pix.setFromAlignedPixels((PixelType*) bmpBits, width, height, channels, pitch);
	} else {
		ofLogError("ofImage") << "putBmpIntoPixels(): unable to set ofPixels from FIBITMAP";
	}
	
	if(bmpConverted != NULL) {
		FreeImage_Unload(bmpConverted);
	}

#ifdef TARGET_LITTLE_ENDIAN
	if(swapForLittleEndian && sizeof(PixelType) == 1) {
		pix.swapRgb();
	}
#endif
}
示例#30
0
// Gets a new FreeImage bitmap if we haven't got one yet or the current one is too small.
// On entry the background thread must not be scanning the bitmap - eg waiting.
// The parameter 'clear' is the value to clear the bitmap to - effectively clears to
// a grey of colour RGB(clear, clear, clear), or -1 to not clear.
void CHexEditDoc::GetAerialBitmap(int clear /*= 0xC0*/)
{
    // If we already have a bitmap make sure it is big enough
    if (dib_ != NULL)
    {
        int dib_size = FreeImage_GetPitch(dib_) * FreeImage_GetHeight(dib_);
        int dib_rows = int(length_/bpe_/MAX_WIDTH) + 2;
        if (dib_size >= MAX_WIDTH*dib_rows*3)
        {
            if (clear > -1)
                memset(FreeImage_GetBits(dib_), clear, dib_size);
            return;
        }

        // Not big enough so free it and reallocate (below)
        FIBITMAP *dib = dib_;
        dib_ = NULL;
        TRACE("+++ FreeImage_Unload(%d)\n", dib);
        FreeImage_Unload(dib);
        if (clear <= -1)
            clear = 0xC0;  // if we get a new bitmap we must clear it
    }

    // TBD: TODO we need user options for default bpe and MAX_BMP (min 16Mb = 1 TByte file @ BPE 65536)
    bpe_ = 1;

    // Keep increasing bpe_ by powers of two until we get a small enough bitmap
    while (bpe_ <= 65536 && (length_*3)/bpe_ > theApp.aerial_max_)
        bpe_ = bpe_<<1;

    // Work out the number of bitmap rows we would need at the widest bitmap size
    int rows = int(length_/bpe_/MAX_WIDTH) + 2;    // Round up to next row plus add one more row to allow for "reshaping"
    ASSERT((rows-2)*MAX_WIDTH < theApp.aerial_max_);

    dib_ = FreeImage_Allocate(MAX_WIDTH, rows, 24);

    dib_size_ = MAX_WIDTH*rows*3;           // DIB size in bytes since we have 3 bytes per pixel and no pad bytes at the end of each scan line
    ASSERT(dib_size_ == FreeImage_GetPitch(dib_) * FreeImage_GetHeight(dib_));
    TRACE("+++ FreeImage_Allocate %d at %p end %p\n", dib_, FreeImage_GetBits(dib_), FreeImage_GetBits(dib_)+dib_size_);
    if (clear > -1)
        memset(FreeImage_GetBits(dib_), clear, dib_size_);       // Clear to a grey
}