示例#1
0
/*!	Converts palette to 16bit GBA colors, compresses it and fills in
	\a gr._palRec.
*/
bool grit_prep_pal(GritRec *gr)
{
    lprintf(LOG_STATUS, "Palette preparation.\n");

    int ii, nclrs, palS;
    COLOR *palOut;
    RGBQUAD *palIn;

    nclrs= gr->palEnd - gr->palStart;
    if(dib_get_nclrs(gr->_dib) < nclrs && nclrs != 0)
        nclrs= dib_get_nclrs(gr->_dib);

    palS= nclrs*sizeof(COLOR);
    palOut= (COLOR*)malloc(palS);
    palIn= &dib_get_pal(gr->_dib)[gr->palStart];

    for(ii=0; ii<nclrs; ii++)
        palOut[ii]= RGB16(palIn[ii].rgbBlue, palIn[ii].rgbGreen, palIn[ii].rgbRed);

    RECORD rec= { 2, palS/2, (BYTE*)palOut };

    if( BYTE_ORDER == BIG_ENDIAN )
        data_byte_rev(rec.data, rec.data, rec_size(&rec), 2);

    // Attach and compress palette
    grit_compress(&rec, &rec, gr->palCompression);
    rec_alias(&gr->_palRec, &rec);

    lprintf(LOG_STATUS, "Palette preparation complete.\n");
    return true;
}
示例#2
0
BOOL CxpGbaDlg::OnInitDialog() 
{
	ASSERT(mpDib);
	
	int nclrs= dib_get_nclrs(mpDib);
	if(nclrs > 0 && mPalStart+mPalCount>nclrs)
	{
		mPalStart= 0;
		mPalCount= nclrs;
	}
	if(moAreaSize != 0)
	{
		mAreaLeft= 0;	mAreaWidth= dib_get_width(mpDib);
		mAreaTop=0;		mAreaHeight= dib_get_height(mpDib);
	}
	if(mbSymChk == FALSE)
		mSymName= mDstTitle;

	CDialog::OnInitDialog();
	OnPalChk();
	OnGfxChk();
	OnMapChk();
	UpdateObj();
	UpdateMap();
	UpdateArea();

	GetDlgItem(IDC_VAR_NAME)->EnableWindow(mbSymChk);

	//UpdateSummary();

	return TRUE;
}
示例#3
0
//! Initialize palette and gfx-related functions from the DIB.
bool grit_init_from_dib(GritRec *gr)
{
	if(gr == NULL)
		return false;

	CLDIB *dib= gr->srcDib;
	if(dib == NULL)
	{
		lprintf(LOG_ERROR, "No bitmap to initialize GritRec from.\n");
		return false;
	}

 	int nclrs = dib_get_nclrs(dib);
	gr->palEnd= ( nclrs ? nclrs : 256 );

	if(dib_get_bpp(dib) > 8)
		gr->gfxBpp= 16;
	else
		gr->gfxBpp= dib_get_bpp(dib);

	gr->areaRight= dib_get_width(dib);
	gr->areaBottom=dib_get_height(dib);

	return true;
}
示例#4
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;
}
示例#5
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;
}
示例#6
0
/*!	Makes sure all the settings in \a gr are valid. For example, 
	tilemap and bitmap mode are mutually exclusive; bpp must be 
	1, 2, 4, 8, or 16 and more of such kind. Some things are fatal
	(those two are), but some can be accounted for like reversed 
	pal start and end indices and non-aligned areas.
*/
bool grit_validate(GritRec *gr)
{
	int tmp;

	lprintf(LOG_STATUS, "Validatating gr.\n");

	// source dib MUST be loaded already!
	if(gr->srcDib == NULL)
	{
		lprintf(LOG_ERROR, "  No input bitmap. Validation failed.\n");
		return false;
	}

	if(!grit_validate_paths(gr))
		return false;

	// --- Options ---

	// bpp must be 2^n; truecolor WILL be bitmaps.
	int bpp= gr->gfxBpp;
	switch(bpp)
	{
	case 0:
		gr->gfxBpp=8;
	case 1: case 2: case 4: case 8:
		break;
	case 16: case 24: case 32:
		gr->gfxBpp= 16;

		gr->mapProcMode= GRIT_EXCLUDE;	// No map. REPONDER
		gr->palProcMode= GRIT_EXCLUDE;	// No pal either.
		break;
	default:
		lprintf(LOG_ERROR, "  Bad bpp (%d).\n", bpp);
		return false;
	}

	// Raw binary cannot be appended
	if(gr->fileType==GRIT_FTYPE_BIN && gr->bAppend)
	{
		gr->bAppend= false;
		lprintf(LOG_WARNING, "  Can't append to binary files. Switching to override mode.");
	}

	// --- ranges ---

	// palette
	if(gr->palProcMode != GRIT_EXCLUDE)
	{
		if(gr->palStart > gr->palEnd)
		{
			lprintf(LOG_WARNING, "  Palette: start (%d) > end (%d): swapping.\n", 
				gr->palStart, gr->palEnd);

			SWAP3(gr->palStart, gr->palEnd, tmp);
		}

		if(gr->palStart<0)
		{
			lprintf(LOG_WARNING, "  Palette: start (%d) < 0. Clamping to 0.\n", 
				gr->palStart);
			gr->palStart= 0;
		}

		int nclrs= dib_get_nclrs(gr->srcDib);
		if(nclrs != 0 && gr->palEnd > gr->palStart+nclrs)
		{
			lprintf(LOG_WARNING, "  Palette: end (%d) > #colors (%d). Clamping to %d.\n", 
				gr->palStart+nclrs);
			gr->palEnd= gr->palStart+nclrs;
		}
	}

	if(!grit_validate_area(gr))
		return false;

	// PONDER: issue dump for status-log?

	lprintf(LOG_STATUS, "Validation succeeded.\n");
	return true;
}
示例#7
0
// === LOAD HELPERS ===================================================
static bool tga_read_pal(CLDIB *dib, const TGAHDR *hdr, 
	FILE *fp)
{
	// no palette, 's fair
	if(hdr->has_table == 0)
		return true;
	// writer of this file is an idiot
	// PONDER: is pal_len the size of the whole thing, or
	//   counting from pal_start?
	//   I'm assuming the latter
	if(hdr->pal_len <= hdr->pal_start)
		return false;

	int ii;
	int clrS= (hdr->pal_bpp != 15 ? (hdr->pal_bpp/8) : 2);
	int palN= hdr->pal_len, palS= palN*clrS;

	BYTE *palD= (BYTE*)malloc(palN*clrS);
	fread(palD, clrS, palN-hdr->pal_start, fp);

	RGBQUAD *dibPal= dib_get_pal(dib);
	memset(dibPal, 0, dib_get_nclrs(dib)*RGB_SIZE);

	if(palN>dib_get_nclrs(dib))
		palN= dib_get_nclrs(dib);
	
	switch(hdr->pal_bpp)	// damn these different options :(
	{
	case 16:
		for(ii=hdr->pal_start; ii<palN; ii++)
		{
			WORD rgb16= ((WORD*)palD)[ii];
			dibPal[ii].rgbRed=   ((rgb16>>10)&31)*255/31;
			dibPal[ii].rgbGreen= ((rgb16>> 5)&31)*255/31;
			dibPal[ii].rgbBlue=  ((rgb16    )&31)*255/31;
		}
		break;
	case 24:
		for(ii=hdr->pal_start; ii<palN; ii++)
		{
			TGA_BGR rgb24= ((TGA_BGR*)palD)[ii];
			dibPal[ii].rgbRed=   rgb24.red;
			dibPal[ii].rgbGreen= rgb24.green;
			dibPal[ii].rgbBlue=  rgb24.blue;
		}
		break;
	case 32:
		for(ii=hdr->pal_start; ii<palN; ii++)
		{
			TGA_BGRA rgb32= ((TGA_BGRA*)palD)[ii];
			dibPal[ii].rgbRed=   rgb32.red;
			dibPal[ii].rgbGreen= rgb32.green;
			dibPal[ii].rgbBlue=  rgb32.blue;
		}
		break;
	default:
		SAFE_FREE(palD);
		return false;
	}

	// clean up
	SAFE_FREE(palD);
	return true;
}
示例#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;
}