cvs: gd /playground/gdbmp gd_bmp.c

[email protected] ("Scott MacVicar") Fri, 15 Feb 2008 04:08:39 -0000
Newsgroups php.gd.cvs
Message-ID <cvsscottmac1203048519@cvsserver>
scottmac		Fri Feb 15 04:08:39 2008 UTC

  Modified files:              
    /gd/playground/gdbmp	gd_bmp.c 
  Log:
  Add support for writing bmp files
  
  
http://cvs.php.net/viewvc.cgi/gd/playground/gdbmp/gd_bmp.c?r1=1.4&r2=1.5&diff_format=u
Index: gd/playground/gdbmp/gd_bmp.c
diff -u gd/playground/gdbmp/gd_bmp.c:1.4 gd/playground/gdbmp/gd_bmp.c:1.5
--- gd/playground/gdbmp/gd_bmp.c:1.4	Thu Jan  3 02:37:45 2008
+++ gd/playground/gdbmp/gd_bmp.c	Fri Feb 15 04:08:39 2008
@@ -9,8 +9,6 @@
 	Todo:
 
 	Bitfield encoding
-	Add full support for Windows v4 and Windows v5 header formats
-	Add write support
 
 	----------------------------------------------------------------------------
  */
@@ -45,6 +43,105 @@
 
 #define BMP_DEBUG(s)
 
+static int gdBMPPutWord(gdIOCtx *out, int w)
+{
+	/* Byte order is little-endian */
+	gdPutC(w & 0xFF, out);
+	gdPutC((w >> 8) & 0xFF, out);
+	return 0;
+}
+
+static int gdBMPPutInt(gdIOCtx *out, int w)
+{
+	/* Byte order is little-endian */
+	gdPutC(w & 0xFF, out);
+	gdPutC((w >> 8) & 0xFF, out);
+	gdPutC((w >> 16) & 0xFF, out);
+	gdPutC((w >> 24) & 0xFF, out);
+	return 0;
+}
+
+BGD_DECLARE(void *) gdImageBmpPtr(gdImagePtr im, int *size)
+{
+	void *rv;
+	gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
+	gdImageBmpCtx(im, out);
+	rv = gdDPExtractData(out, size);
+	out->gd_free(out);
+	return rv;
+}
+
+BGD_DECLARE(void) gdImageBmp(gdImagePtr im, FILE *outFile)
+{
+	gdIOCtx *out = gdNewFileCtx(outFile);
+	gdImageBmpCtx(im, out);
+	out->gd_free(out);
+}
+
+BGD_DECLARE(void) gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out)
+{
+	int bitmap_size, info_size, total_size;
+	int i, row, xpos, pixel;
+
+	bitmap_size = ((im->sx * (im->trueColor ? 24 : 8)) / 8) * im->sy;
+	/* 40 byte Windows v3 header */
+	info_size = BMP_WINDOWS_V3;
+
+	/* data for the palette */
+	if (!im->trueColor)
+	{
+		info_size += im->colorsTotal * 4;
+	}
+
+	/* bitmap header + info header + data */
+	total_size = 14 + info_size + bitmap_size;
+
+	/* write bmp header info */
+	gdPutBuf("BM", 2, out);
+	gdBMPPutInt(out, total_size);
+	gdBMPPutWord(out, 0);
+	gdBMPPutWord(out, 0);
+	gdBMPPutInt(out, 14 + info_size);
+	
+	/* write Windows v3 headers */
+	gdBMPPutInt(out, BMP_WINDOWS_V3); /* header size */
+	gdBMPPutInt(out, im->sx); /* width */
+	gdBMPPutInt(out, im->sy); /* height */
+	gdBMPPutWord(out, 1); /* colour planes */
+	gdBMPPutWord(out, (im->trueColor ? 24 : 8)); /* bit count */
+	gdBMPPutInt(out, BMP_BI_RGB); /* compression */
+	gdBMPPutInt(out, bitmap_size); /* image size */
+	gdBMPPutInt(out, 0); /* H resolution */
+	gdBMPPutInt(out, 0); /* V ressolution */
+	gdBMPPutInt(out, im->colorsTotal); /* colours used */
+	gdBMPPutInt(out, 0); /* important colours */
+
+	/* 16-bit colours */
+	if (!im->trueColor) {
+		for(i = 0; i< im->colorsTotal; ++i) {			
+			Putchar(gdImageBlue(im, i), out);
+			Putchar(gdImageGreen(im, i), out);
+			Putchar(gdImageRed(im, i), out);
+			Putchar(0, out);
+        }
+        for (row = im->sy; row > 0; row--) {
+			for (xpos = 0; xpos < im->sx; xpos++) {
+				Putchar(gdImageGetPixel(im, xpos, row), out);
+			}	
+		}
+	} else {
+        for (row = im->sy; row > 0; row--) {
+			for (xpos = 0; xpos < im->sx; xpos++) {
+				pixel = gdImageGetPixel(im, xpos, row);
+				
+				Putchar(gdTrueColorGetBlue(pixel), out);
+				Putchar(gdTrueColorGetGreen(pixel), out);
+				Putchar(gdTrueColorGetRed(pixel), out);
+			}	
+		}
+	}
+}
+
 BGD_DECLARE(gdImagePtr) gdImageCreateFromBmp(FILE * inFile)
 {
 	gdImagePtr im = 0;