Exemple #1
0
/*!	Prepares the work dib for export, i.e. converts to the final
	bitdepth, compresses the data and fills in \a gr._gfxRec.
*/
bool grit_prep_gfx(GritRec *gr)
{
    lprintf(LOG_STATUS, "Graphics preparation.\n");

    int srcB= dib_get_bpp(gr->_dib);	// should be 8 or 16 by now
    int srcP= dib_get_pitch(gr->_dib);
    int srcS= dib_get_size_img(gr->_dib);
    BYTE *srcD= dib_get_img(gr->_dib);

    int dstB= gr->gfxBpp;
    // # dst bytes, with # src pixels as 'width'
    int dstS= dib_align(srcS*8/srcB, dstB);
    dstS= ALIGN4(dstS);
    BYTE *dstD= (BYTE*)malloc(dstS);
    if(dstD == NULL)
    {
        lprintf(LOG_ERROR, "  Can't allocate graphics data.\n");
        return false;
    }

    // Convert to final bitdepth
    // NOTE: do not use dib_convert here, because of potential
    //   problems with padding
    // NOTE: we're already at 8 or 16 bpp here, with 16 bpp already
    //   accounted for. Only have to do 8->1,2,4
    // TODO: offset
    if(srcB == 8 && srcB != dstB)
    {
        lprintf(LOG_STATUS, "  Bitpacking: %d -> %d.\n", srcB, dstB);
        data_bit_pack(dstD, srcD, srcS, srcB, dstB, 0);
    }
    else
        memcpy(dstD, srcD, dstS);

    RECORD rec= { 1, dstS, dstD };

    if( BYTE_ORDER == BIG_ENDIAN && gr->gfxBpp > 8 )
        data_byte_rev(rec.data, rec.data, rec_size(&rec), gr->gfxBpp/8);

    // attach and compress graphics
    grit_compress(&rec, &rec, gr->gfxCompression);
    rec_alias(&gr->_gfxRec, &rec);

    lprintf(LOG_STATUS, "Graphics preparation complete.\n");
    return true;
}
Exemple #2
0
// xxx_load(const char *fname, PDIBDATA *ppdib, IMG_FMT_INFO *pifi)
bool CTgaFile::Load(const char *fpath)
{
	FILE *fp= fopen(fpath, "rb");
	CLDIB *dib= NULL;
	TGAHDR hdr;

	try
	{
		if(!fp)
			throw CImgFile::sMsgs[ERR_NO_FILE];

		fread(&hdr, sizeof(TGAHDR), 1, fp);

		// ignore image desc (if any)
		fseek(fp, hdr.id_len, SEEK_CUR);

		int imgW, imgH, imgB, imgP;
		imgW= hdr.width;
		imgH= hdr.height;
		imgB= hdr.img_bpp;
		imgP= dib_align(imgW, imgB);

		// Set-up the full bitmap
		dib= dib_alloc(imgW, imgH, imgB, NULL, true);
		if(dib == NULL)
			throw CImgFile::sMsgs[ERR_ALLOC];

		// === get color map ===
		if(hdr.has_table)
		{
			if(!tga_read_pal(dib, &hdr, fp))
				throw sMsgs[ERR_TGA_BADPAL];
		}

		int ii;
		int tgaP= (imgW*imgB+7)/8;
		BYTE *imgD= dib_get_img(dib);

		switch(hdr.type)
		{
		case TGA_BW:
		case TGA_PAL:
		case TGA_true:
			for(ii=0; ii<imgH; ii++)
				fread(&imgD[ii*imgP], 1, tgaP, fp);
			break;
		case TGA_BW_RLE:
		case TGA_PAL_RLE:
		case TGA_true_RLE:
			tga_unrle(dib, &hdr, fp);
			break;
		default:
			throw sMsgs[ERR_TGA_VERSION];
		}

		// TGA's are bottom-up by default, flip if necessary
		if(~hdr.img_desc & TGA_VFLIP)
			dib_vflip(dib);

	}	// </try>
	catch(const char *msg)
	{
		SetMsg(msg);
		dib_free(dib);
		dib= NULL;
	}
	// cleanup
	if(!dib)
		return false;

	// if we're here we've succeeded
	SetMsg(CImgFile::sMsgs[ERR_NONE]);
	dib_free(Attach(dib));

	SetBpp(dib_get_bpp(dib));
	SetPath(fpath);

	return true;
}
Exemple #3
0
// Yes, you can use LoadImage too, but that creates a device 
// dependent bitmap and you want to stay the fsck away from those.
bool CBmpFile::Load(const char *fpath)
{
	FILE *fp= fopen(fpath, "rb");
	CLDIB *dib= NULL;

	try
	{
		if(!fp)
			throw CImgFile::sMsgs[ERR_NO_FILE];

		BITMAPFILEHEADER bmfh;
		fread(&bmfh,  sizeof(BITMAPFILEHEADER), 1,fp);

		// Whoa, not a bitmap, back off
		if(bmfh.bfType != BMP_TYPE)	// 4D42h = "BM". 
			throw CImgFile::sMsgs[ERR_FORMAT];

		BITMAPINFOHEADER bmih;
		bool bCore;

		// check for bm version first :(
		fread(&bmih, 4, 1, fp);
		if(bmih.biSize == sizeof(BITMAPCOREHEADER))		// crap! v2.x BMP
		{
			bCore= true;
			bmih.biSize= BMIH_SIZE; 
			WORD wd;
			fread(&wd, 2,1,fp);
			bmih.biWidth= wd;
			fread(&wd, 2,1,fp);
			bmih.biHeight= wd;
			fread(&bmih.biPlanes, 2,1,fp);
			fread(&bmih.biBitCount, 2,1,fp);
			memset(&bmih.biCompression, 0, 
				BMIH_SIZE-sizeof(BITMAPCOREHEADER));
		}
		else		// normal v3.0 BMP
			fread(&bmih.biWidth, BMIH_SIZE-4, 1, fp);

		if(bmih.biPlanes > 1)				// no color planes, plz
			throw sMsgs[ERR_BMP_PLANES];
		if(bmih.biCompression != BI_RGB)	// no compression either
			throw sMsgs[ERR_BMP_CPRS];

		int dibP, dibHa, dibS;

		dibHa= abs(bmih.biHeight);
		dibP= dib_align(bmih.biWidth, bmih.biBitCount);
		dibS= dibP*dibHa;
		// set manually, just to be sure
		bmih.biSizeImage= dibS;

		// ditto for ClrUsed
		if(bmih.biBitCount <=8 && bmih.biClrUsed == 0)
			bmih.biClrUsed= 1<<bmih.biBitCount;

		// now we set-up the full bitmap
		dib= dib_alloc(bmih.biWidth, dibHa, bmih.biBitCount, NULL, true);
		if(dib == NULL)
			throw CImgFile::sMsgs[ERR_ALLOC];

		// read the palette
		fread(dib_get_pal(dib), RGB_SIZE, bmih.biClrUsed, fp);

		// read image
		fread(dib_get_img(dib), dibS, 1, fp);
		if(bmih.biHeight>=0)	// -> TD image
			dib_vflip(dib);

	}	// </try>
	catch(const char *msg)
	{
		SetMsg(msg);
		dib_free(dib);
		dib= NULL;
	}
	if(fp)
		fclose(fp);
	if(!dib)
		return false;

	// if we're here we've succeeded
	SetMsg(CImgFile::sMsgs[ERR_NONE]);
	dib_free(Attach(dib));

	SetBpp(dib_get_bpp(dib));
	SetPath(fpath);

	return true;
}
Exemple #4
0
/*!	\param width	Bitmap width
*	\param height	Bitmap height
*	\param bpp	Bitmap bitdepth (1, 4, 8, 16, 24, 32)
*	\param data	Data to fill the bitmap with. If \c NULL, data will 
*	  be uninitialized.
*	\param bTopDown	If \c true, the bitmap will be top-down (origin in 
*	  the top-left); if \c false, it'll be bottom up. Windows bitmaps 
*	  are traditionally bottom-up, with all the awkwardness that goes 
*	  with it (as matrices and screens are usually top-down). 
*	  \c CLDIBs are top-down by default.
*	\note	Always call \c dib_free() on bitmaps when you're done with it.
*/
CLDIB *dib_alloc(int width, int height, int bpp, const BYTE *data,
	bool bTopDown /* true */)
{
	int ii;
	CLDIB *dib= NULL;

	// check validity of requested bpp
	const int bpp_allowed[6]= { 1, 4, 8, 16, 24, 32 };
	for(ii=0; ii<6; ii++)
		if(bpp == bpp_allowed[ii])
			break;
	if(ii >= 6)
		return NULL;
	
	int nclrs, dibH, dibP, dibS;
	nclrs= (bpp > 8 ? 0 : 1<<bpp);
	dibH= height;
	dibP= dib_align(width, bpp);
	dibS= dibP*dibH;

	// create in two stages, first the dib itself, and then for the data
	// and conk out if either fails
	dib= (CLDIB*)malloc(sizeof(CLDIB));
	if(dib == NULL)
		return NULL;

	dib->data= (BYTE*)malloc(BMIH_SIZE + nclrs*RGB_SIZE + dibS);
	if(dib->data == NULL)
	{
		free(dib);
		return NULL;
	}

	BITMAPINFOHEADER *bmih= dib_get_hdr(dib);

	bmih->biSize= BMIH_SIZE;
	bmih->biWidth= width;
	bmih->biHeight= bTopDown ? -height : height;
	bmih->biPlanes= 1;
	bmih->biBitCount= bpp;
	bmih->biCompression= 0;
	bmih->biSizeImage= dibS; 
	bmih->biXPelsPerMeter= 0; 
	bmih->biYPelsPerMeter= 0; 
	bmih->biClrUsed= nclrs; 
	bmih->biClrImportant= 0;

	// init palette, all reds, corresponding to COLORREFs [0-nclrs>
	// PONDER: is this right?
	COLORREF *clr= (COLORREF*)dib_get_pal(dib);
	for(ii=0; ii<nclrs; ii++)
		clr[ii]= ii<<16;


	// init data
	if(data != NULL)
	{
		if(bTopDown)
			memcpy(dib_get_img(dib), data, dibS);
		else
		{
			const BYTE *srcL= &data[(height-1)*dibP];
			BYTE *dstL= dib_get_img(dib);
			for(ii=0; ii<height; ii++)
				memcpy(&dstL[ii*dibP], &srcL[-ii*dibP], dibP);
		}
	}

	return dib;
}