Newsgroup: it.comp.programmare
Titolo: ! BMP, Come scriverne uno?

Salve,
come posso scrivere un windows bitmap(bmp)?
So che inizia con una struttura che descrive il file, e poi iniziano i byte
dell'immagine.  Com'e' la struttura, come devo scrivere i bits
dell'immagine?
Sarei interessato ad implementare io stesso una funzione per scrivere BMP, e
non ad utilizzare qualche dll o controllo esistente!
Grazie in anticipo come al solito,



Copio e incollo da un file che forse ti puo' essere d'aiuto:
INDEX_HANDLER  ndxmgr[]=
{
  {	".bin", BINARY, Open_BIN, Make_BIN, Find_BIN, Ins_BIN, Del_BIN,
NULL },
  {	".btr",	BTREE,  Open_BTR, Make_BTR, Find_BTR, Ins_BTR, Del_BTR,
NULL },
  {	".avl",	AVL,    Open_AVL, Make_AVL, Find_AVL, Ins_AVL, Del_AVL,
NULL },
  {	".ntx",	CLIPPER,Open_NTX, Make_NTX, Find_NTX, Ins_NTX, Del_NTX,
NULL },
  {	".ndx",	DBASE,	Open_NDX, Make_NDX, Find_NDX, Ins_NDX, Del_NDX,
NULL },
  {	".txt",	TEXT,   Open_TXT, Make_TXT, Find_TXT, Ins_TXT, Del_TXT,
NULL },
  {	NULL,	0,	NULL,     NULL,     NULL,     NULL,    NULL
},
};
HEADER  sourceBitmap=
{
	BMP_SIGN,
	0,
	0,
	0,	/* Header size including palette */
	0x28,	/* Structure size */
	0,
	0,
	1,
	1,
	0,	/* No compression */
	0,
	2835,
	2835,
	0,
	0
};
DWORD	RasterBytes(DWORD pixels, int bits)
{
	return
	(
	   (((pixels * bits) >> 3 ) + 3 )
	   & (~3L)
	);
}
DWORD	RasterSeek(DWORD width, DWORD height, int bits, DWORD x, DWORD
y)
{
	DWORD temp;
	temp = height - y;			/* Offset in rows
*/
	temp*= RasterBytes(width, bits);	/* Offset in bytes
*/
	temp+= ((x * bits) >> 3);		/* Plus X-Offset
*/
	temp+= sizeof(HEADER);			/* Plus header
*/
	temp+= ((1<<bits)<<2);			/* Plus palette
*/
	return temp;
}
/*
	Creates a bitmap "name" responding to a given header and
palette.
	Returns stream if successful, NULL if an error occurred
	A background bitpattern is taken from World description.
*/
FILE	*BuildBitmap(BYTE *name, HEADER *bitmap, PALETTE *palette)
{
	FILE	*fp;
	DWORD	x, y;
	BYTE	*raster;
	int	i,j,z;
	fp = fopen(name,"w+b");
	if (!fp)
	{
		strerr = "Cannot create bitmap -- permission denied or
disk full";
		return NULL;
	}
	if (fwrite (bitmap, sizeof(HEADER), 1, fp)!=1)
	{
		fclose(fp);
		unlink(name);
		strerr = "Cannot initialize bitmap -- disk full?";
		return NULL;
	}
	if (bitmap->biBitCount < 15)
	{
		/* Write palette using defaults - i.e. target */
		if (palette)
		{
			if (fwrite(World->palette, sizeof(PALETTE),
1<<bitmap->biBitCount, fp)!= (size_t)(1<<bitmap->biBitCount))
			{
				strerr = "Cannot initialize bitmap
palette -- disk full?";
				fclose(fp);
				unlink(name);
				return NULL;
			}
		}
		else
		{
			if (World->palette)
			{
				if (fwrite(World->palette,
sizeof(PALETTE), 1<<bitmap->biBitCount,
fp)!=(size_t)(1<<bitmap->biBitCount))
				{
					strerr = "Cannot initialize
bitmap palette -- disk full?";
					fclose(fp);
					unlink(name);
					return NULL;
				}
				/* Go for Gold! - gray, 09/1998 */
			}
			else
			{
				strerr = "Segmentation fault: no palette
data, and no default!";
				fclose(fp);
				unlink(name);
				return NULL;
			}
		}
	}
        if ((raster = (BYTE *)malloc (BITBUFFER))==NULL)
	{
		strerr = "Cannot initialize bitbuffer -- out of memory";
		fclose(fp);
		unlink(name);
		return NULL;
	}
	y = bitmap->biHeight;
	x = RasterBytes(bitmap->biWidth, bitmap->biBitCount);
	z = (WORD)(BITBUFFER / x);	/* Perhaps can dump > 1 lines at
a time? */
	if (!z)
		z = 1;
	for (i=0; i<(((BITBUFFER/3)*3)/z) ; i++)
	{
		DWORD blit = World->bitpattern;
		for (j=0;j<z;j++)
			raster[i*z]=(BYTE)(blit & 0xFF);/***/
		blit >>= 8;
		i++;
		for (j=0;j<z;j++)
			raster[i*z]=(BYTE)(blit & 0xFF);/***/
		blit >>= 8;
		i++;
		for (j=0;j<z;j++)
			raster[i*z]=(BYTE)(blit & 0xFF);/***/
		i++;
	}
	while(y)
	{
		DWORD	outbytes;
		size_t  chunk;
		if (y < (DWORD)z)	/* Last y (< z) rows */
			z = (WORD) y;
		outbytes = x*z;
		while(outbytes)
		{
			if (outbytes < BITBUFFER)
				chunk = (size_t) outbytes;
			else
				chunk = (BITBUFFER/3)*3;
			if (fwrite (raster, chunk, 1, fp)!=1)
			{
				strerr = "Cannot initialize bitmap --
disk full?";
				fclose(fp);
				unlink(name);
				return NULL;
			}
			outbytes -= chunk;
		}
		y-=z;
	}
        free (raster);
	return fp;
}
/* Ritorna l'indirizzo del primo byte della y-esima linea del file
   descritto da hinfo */
DWORD location(HEADER *hinfo, DWORD y)
{
	/* This one is better ;-) (gray, 11/1998) */
	return	RasterSeek(hinfo->biWidth,
			   hinfo->biHeight,
			   hinfo->biBitCount,
			   0,
			   y);
/*
	// This code is crappy! (ftagghua 09/1998)
	DWORD LineSize, DataStart = sizeof(HEADER);
	LineSize =(hinfo->biWidth*hinfo->biBitCount+7)>>3;
	LineSize += 0x0003L;
	LineSize &=~0x0003L;
	DataStart += ((1<<(hinfo->biBitCount-1))<<2);
	return DataStart+(hinfo->biHeight-y)*LineSize;
*/
}
/* MERGE in1 in2 width height dx dy cout xpos ypos
   Merges in1 and in2 into a single bitmap, width by height pixels.
   Bitmap in1 is taken from (0,0) and bitmap in2 from (dx,dy).
   The result bitmap is at (xpos, ypos) relative to in1.
   - a) Call to CHUNK to extract first piece from in1 and put in cout
	ChunkBitmap(in1, cout , width, height, xpos, ypos)
   - b) Call to CHUNK to extract second piece from in2 and put in (tmp)
	ChunkBitmap(in2, $TMP$, width, height, xpos+dx,ypos+dy)
   - c) Call to DumpBitmapOverBitmap to dump (tmp) onto cout
	DumpBitmapOverBitmap
   - delete (tmp):
HEADER	*newBitmap(void)
{
	HEADER *tmp;
        if ((tmp = malloc(sizeof(HEADER)))==NULL)
		return NULL;
	tmp->Signature          = BMP_SIGN;
	tmp->FileSize           = 0;
	tmp->WonderWhat         = 0;
	tmp->hdSize             = 0;      /* Header size including
palette */
	tmp->biSize             = 0x28;   /* Structure size */
	tmp->biWidth            = 0;
	tmp->biHeight           = 0;
	tmp->biPlanes           = 1;
	tmp->biBitCount         = 1;
	tmp->biCompression      = 0;      /* No compression (we may use
WKL but we lose Windows compatibility ) */
	tmp->biSizeImage        = 0;
	tmp->biXPelsPerMeter    = 2835;	/* Fixed res and go for Gold! */
	tmp->biYPelsPerMeter    = 2835;
	tmp->biClrUsed          = 0;
	tmp->biClrImportant     = 0;
        return tmp;
}
Leonardo
".signature": bad command or file name

www.wotsit.org
