Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
//! Flip a bitmap horizontally (8, 16, 24, 32)
bool dib_hflip(CLDIB *dib)
{
	if(dib == NULL) 
		return false;
			
	int dibW, dibH, dibB, dibP;
	dib_get_attr(dib, &dibW, &dibH, &dibB, &dibP);

	if(dibB < 8)
		return false;

	BYTE *dibL, *bufD;

	bufD= (BYTE*)malloc(dibP);
	if(bufD == NULL)
		return false;

	dibL= dib_get_img(dib);

	int ix, iy, ib, nb= dibB/8;
	
	for(iy=0; iy<dibH; iy++)
	{	
		memcpy(bufD, dibL, dibP);

		//# TODO: 1, 4 bpp
		
		for(ix=0; ix<dibW; ix++)
		{
			for(ib=0; ib<nb; ib++)
				dibL[ix*nb+ib] = bufD[(dibW-1-ix)*nb+ib];
		}
		dibL += dibP;
	}

	free(bufD);

	return true;
}
Ejemplo n.º 3
0
/*!	\param dib	DIB to reduce the palette of. Must be paletted. Pixels 
		will be rearranged to match the palette.
	\param extPal	External palette record. \a dib will use this 
		and its own palette. Can be NULL. The new reduced palette goes here too.
	\return	Number of reduced colors, or 0 if not 8bpp. 
	\note	The order of colors is the order of appearance, except for the 
		first one.
*/
int dib_pal_reduce(CLDIB *dib, RECORD *extPal)
{
	// Only for 8bpp (for now)
	if(dib == NULL || dib_get_bpp(dib) != 8)
		return 0;

	int ii, jj, kk, ix, iy;

	int dibW, dibH, dibP;
	dib_get_attr(dib, &dibW, &dibH, NULL, &dibP);

	BYTE *dibD= dib_get_img(dib);

	// Get palette histogram
	int histo[256];

	memset(histo, 0, sizeof(histo));
	for(iy=0; iy<dibH; iy++)
		for(ix=0; ix<dibW; ix++)
			histo[dibD[iy*dibP+ix]]++;

	// Allocate room for new palette and init with ext pal
	// NOTE: extPal is assumed reduced!
	// NOTE: double-size for rdxPal for worst-case scenario.
	// NOTE: the *Clr things are just to make comparisons easier.
	//		 pointers ftw!

	int count;
	RGBQUAD *rdxPal= (RGBQUAD*)malloc(512*RGB_SIZE);
	COLORREF *rdxClr= (COLORREF*)rdxPal, *dibClr= (COLORREF*)dib_get_pal(dib);

	memset(rdxPal, 0, 512*RGB_SIZE);
	if(extPal != NULL && extPal->data != NULL)
	{
		memcpy(rdxPal, extPal->data, rec_size(extPal));
		count= extPal->height;
	}
	else
	{
		rdxClr[0]= dibClr[0];
		count= 1;
	}

	// PONDER: always keep index 0 ?

	// Create reduced palette and prep tables for pixel conversion.
	DWORD srcIdx[PAL_MAX], dstIdx[PAL_MAX];

	kk=0;
	for(ii=0; ii<PAL_MAX; ii++)
	{
		if(histo[ii])
		{
			for(jj=0; jj<count; jj++)
				if(rdxClr[jj] == dibClr[ii])
					break;
			// Match: add color to table
			if(jj == count)
			{
				rdxClr[jj]= dibClr[ii];
				count++;
			}
			srcIdx[kk]= jj;
			dstIdx[kk]= ii;
			kk++;
		}
	}

	// PONDER: what *should* happen if nn > PAL_MAX ?
	// Fail, trunc or re-quantize?

	//  Update palette and remap pixels
	memcpy(dibClr, rdxClr, PAL_MAX*RGB_SIZE);
	dib_pixel_replace(dib, dstIdx, srcIdx, kk);

	// Update rdxPal's data
	if(extPal)
	{
		extPal->width= RGB_SIZE;
		extPal->height= count;
		free(extPal->data);

		extPal->data= (BYTE*)malloc(count*RGB_SIZE);
		memcpy(extPal->data, rdxClr, count*RGB_SIZE);
	}

	return count;
}