Exemplo n.º 1
0
/*!	\param dib bitmap to flip.
*	\note This is an in-place flip.
*/
bool dib_vflip(CLDIB *dib)
{
	BYTE *topL, *botL, *tempD;

	if(dib == NULL) 
		return false;

	DWORD dibP= dib_get_pitch(dib), dibH= dib_get_height(dib);
	tempD= (BYTE*)malloc(dibP);
	if(tempD == NULL)
		return false;

	topL= dib_get_img(dib);
	botL= topL+dibP*(dibH-1);

	dibH /= 2;
	while(dibH--)
	{
		memcpy(tempD, topL, dibP);
		memcpy(topL, botL, dibP);
		memcpy(botL, tempD, dibP);
		topL += dibP;
		botL -= dibP;
	}
	free(tempD);

	return true;
}
Exemplo n.º 2
0
// CHK: unpadded works
// DESC: redimensions/(un)tiles a dib into a column of tiles with 
//   dimensions dstW x tileH. Can also work in reverse (if srcW<dstW)
// NOTE: padding pixels may cause problems
CLDIB *dib_redim_copy(CLDIB *src, int dstW, int tileH, int tileN)
{
	if(src == NULL)
		return NULL;

	int srcW, srcH, srcB, srcP;
	dib_get_attr(src, &srcW, &srcH, &srcB, &srcP);

	// Force byte alignment
	if( (dstW*srcB&7) )
		return NULL;

	// setup redim
	int srcR= srcW*srcB>>3, dstR= dstW*srcB>>3;	// bytes/row

	RECORD srcRec= { srcR, srcH, dib_get_img(src) };
	RECORD dstRec= { dstR, 0, 0 };

	int ii;
	BYTE *srcD= NULL;

	if(srcR&3)	// depad for src
	{
		srcD= (BYTE*)malloc(srcR*srcH);
		if(srcD == NULL)
			return NULL;
		for(ii=0; ii<srcH; ii++)
			memcpy(&srcD[ii*srcR], &srcRec.data[ii*srcP], srcR);
		srcRec.data= srcD;
	}
	bool bOK= data_redim(&srcRec, &dstRec, tileH, tileN);
	SAFE_FREE(srcD);
	if(!bOK)
		return NULL;

	CLDIB *dst= dib_alloc(dstW, dstRec.height, srcB, NULL, dib_is_topdown(src));
	if(dst == NULL)
		return NULL;

	int dstH= dib_get_height(dst);	// bytes/row
	int dstP= dib_get_pitch(dst);
	BYTE *dstD= dib_get_img(dst);

	if(dstR&3)	// repad for dst
	{
		for(ii=0; ii<dstH; ii++)
			memcpy(&dstD[ii*dstP], &dstRec.data[ii*dstR], dstP);
	}
	else
		memcpy(dstD, dstRec.data, dstP*dstH);
	SAFE_FREE(dstRec.data);

	memcpy(dib_get_pal(dst), dib_get_pal(src), 
		dib_get_nclrs(src)*RGB_SIZE);

	return dst;
}
Exemplo n.º 3
0
bool CBmpFile::Save(const char *fpath)
{
	FILE *fp= NULL;
	bool bOK= true;;

	try
	{
		if(!mDib)
			throw CImgFile::sMsgs[ERR_GENERAL];

		fp = fopen(fpath, "wb");
		if(!fp)
			throw CImgFile::sMsgs[ERR_NO_FILE];

		BITMAPINFOHEADER bmih= *dib_get_hdr(mDib);
		int dibH= dib_get_height2(mDib), dibHa= dib_get_height(mDib);
		int dibP= dib_get_pitch(mDib), dibPa= dibP;
		int dibS= dibHa*dibPa, nclrs= dib_get_nclrs(mDib);

		bmih.biHeight= dibHa;
		bmih.biSizeImage= dibS;

		// fill in fileheader
		BITMAPFILEHEADER bmfh;
		bmfh.bfType= BMP_TYPE;
		bmfh.bfOffBits= sizeof(BITMAPFILEHEADER)+BMIH_SIZE+nclrs*RGB_SIZE;
		bmfh.bfSize= bmfh.bfOffBits + dibS;
		bmfh.bfReserved1= bmfh.bfReserved2= 0;

		// write down header
		fwrite(&bmfh, sizeof(BITMAPFILEHEADER), 1, fp);
		fwrite(&bmih, BMIH_SIZE, 1, fp);
		// write down palette
		fwrite(dib_get_pal(mDib), RGB_SIZE, nclrs, fp);

		// write down rows, with possible flipping
		BYTE *dibL= dib_get_img(mDib);
		if(dibH<0)
		{
			dibL += (dibHa-1)*dibPa;
			dibP= -dibP;
		}
		for(int iy=0; iy<dibHa; iy++)
			fwrite(dibL+iy*dibP, dibPa, 1, fp);
	}
	catch(const char *msg)
	{
		SetMsg(msg);
		bOK= false;
	}

	if(fp)
		fclose(fp);	

	return bOK;
}
Exemplo n.º 4
0
// TGA RLE;
// * lines are byte-aligned
// * RLE can cross lines
// * RLE works by the pixel for true clr, by byte for paletted
// * The RLE header byte, ch:
//   ch{0-6} : # chunks -1
//   ch{7}   : stretch.
void tga_unrle(CLDIB *dib, TGAHDR *hdr, FILE *fp)
{
	int ii, ix, iy;
	int imgW= dib_get_width(dib);
	int imgH= dib_get_height(dib);
	int imgB= dib_get_bpp(dib);
	int imgP= dib_get_pitch(dib);
	BYTE *imgL= dib_get_img(dib), *imgEnd= imgL+imgH*imgP;

	int tgaP= (imgW*imgB+7)/8;	// pseudo pitch
	int tgaN= (imgB+7)/8;		// chunk size
	BYTE ch, chunk[4];

	ix=0, iy=0;
	while(1)
	{
		ch= fgetc(fp);
		if(ch>127)			// stretch
		{
			ch -= 127;
			fread(chunk, 1, tgaN, fp);
			while(ch--)
			{
				for(ii=0; ii<tgaN; ii++)
					imgL[ix+ii]= chunk[ii];
				ix += tgaN;

				if(ix >= tgaP)
				{
					imgL += imgP;
					ix= 0;
					if(imgL >= imgEnd)
						return;
				}
			}
		} // </stretch>
		else				// no stretch
		{
			ch++;
			while(ch--)
			{
				fread(&imgL[ix], 1, tgaN, fp);
				ix += tgaN;
				if(ix >= tgaP)
				{
					imgL += imgP;
					ix= 0;
					if(imgL >= imgEnd)
						return;
				}
			}
		} // </no stretch>
	} // </while(1)>
}
Exemplo n.º 5
0
/*! Similar to \c dib_clone, but can crop the image too. The 
*	boundaries of the new bitmap need not fit inside the source; the 
*	outside parts will be zeroed.
*	\param src Source bitmap.
*	\param ll Left of rectangle.
*	\param tt Top of rectangle.
*	\param rr Right of rectangle.
*	\param bb Bottom of rectangle.
*	\param bClip If \c true, the rectangle will be clipped to the 
*	  dimensions of \c src.
*	\return Copied and cropped bitmap.	
*/
CLDIB *dib_copy(CLDIB *src, int ll, int tt, int rr, int bb, bool bClip)
{
	if(src==NULL || ll==rr || tt==bb)
		return NULL;

	int srcW= dib_get_width(src);
	int srcH= dib_get_height(src);
	int srcB= dib_get_bpp(src);
	int srcP= dib_get_pitch(src);

	// Normalize rect
	if(rr<ll)
	{	int tmp=ll; ll=rr; rr=tmp;	}
	if(bb<tt)
	{	int tmp=tt; tt=bb; bb=tmp;	}

	// Clip if requested
	if(bClip)
	{
		if(ll<0)	ll= 0;
		if(tt<0)	tt= 0;
		if(rr>srcW)	rr= srcW;
		if(bb>srcH) bb= srcH; 
	}

	int dstW= rr-ll, dstH= bb-tt;
	CLDIB *dst= dib_alloc(dstW, dstH, srcB, NULL, true);
	if(dst==NULL)
		return NULL;
	
	dib_pal_cpy(dst, src);

	// set base src,dst pointers
	int dstP= dib_get_pitch(dst);
	BYTE *srcL= dib_get_img(src), *dstL= dib_get_img(dst);

	if(ll>=0)	// set horz base
		srcL += ll*srcB>>3;
	else
Exemplo n.º 6
0
//! Get the main attributes of a DIB
bool dib_get_attr(CLDIB *dib, int *width, int *height, int *bpp, int *pitch)
{
	if(dib == NULL)
		return false;

	if(width)
		*width= dib_get_width(dib);
	if(height)
		*height= dib_get_height(dib);
	if(bpp)
		*bpp= dib_get_bpp(dib);
	if(pitch)
		*pitch= dib_get_pitch(dib);
	return true;
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
bool CTgaFile::Save(const char *fpath)
{

	int ii, iy;
	FILE *fp= NULL;
	bool bOK= true;

	try
	{
		if(!mDib)
			throw CImgFile::sMsgs[ERR_GENERAL];

		fp = fopen(fpath, "wb");
		if(!fp)
			throw CImgFile::sMsgs[ERR_NO_FILE];

		int imgW= dib_get_width(mDib);
		int imgH= dib_get_height(mDib), imgHs= dib_get_height2(mDib);
		int imgP= dib_get_pitch(mDib);
		int imgB= dib_get_bpp(mDib);
		int imgS= imgH*imgP, nclrs= dib_get_nclrs(mDib);

		TGAHDR hdr;
		memset(&hdr, 0, sizeof(TGAHDR));

		if(imgB==1)
			hdr.type= TGA_BW;
		else if(imgB <= 8)
			hdr.type= TGA_PAL;
		else
			hdr.type= TGA_true;

		if(imgB<=8)		// paletted
		{
			hdr.has_table= 1;
			hdr.pal_len= dib_get_nclrs(mDib);
			hdr.pal_bpp= 24;
		}
		else			// true color
			hdr.has_table=0;

		hdr.width= imgW;
		hdr.height= imgH;
		hdr.img_bpp= imgB;
		hdr.img_desc= 0;

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

		// write palette
		if(imgB <= 8)
		{
			RGBQUAD *pal= dib_get_pal(mDib);
			for(ii=0; ii<hdr.pal_len; ii++)
				fwrite(&pal[ii], 1, 3, fp);
		}

		// TGA should be bottom up:
		BYTE *imgL= dib_get_img(mDib);
		if(dib_is_topdown(mDib))
		{
			imgL += imgP*(imgH-1);
			imgP= -imgP;
		}

		// write image (not RLEd, because that's awful to do)
		int tgaP= (imgW*imgB+7)/8;
		for(iy=0; iy<imgH; iy++)
			fwrite(&imgL[iy*imgP], 1, tgaP, fp);
	}
	catch(const char *msg)
	{
		SetMsg(msg);
		bOK= false;
	}

	if(fp)
		fclose(fp);	

	return bOK;
}
Exemplo n.º 9
0
/*!	\note	Works at the byte level. If you have sub-8 bpps, you'll
*	  still have to shift a bit.
*/
BYTE *dib_get_img_at(CLDIB *dib, int x, int y)
{
	BYTE *dibD= dib_get_img(dib);
	return &dibD[x*dib_get_bpp(dib)/8 + y*dib_get_pitch(dib)];
}