[Bf-blender-cvs] [d8435596d5a] master: imbuf: support writing grayscale BMP images

James Fulop noreply at git.blender.org
Wed Jan 29 02:41:31 CET 2020


Commit: d8435596d5af76537137a7d3f40afce271223095
Author: James Fulop
Date:   Wed Jan 29 12:37:14 2020 +1100
Branches: master
https://developer.blender.org/rBd8435596d5af76537137a7d3f40afce271223095

imbuf: support writing grayscale BMP images

===================================================================

M	source/blender/blenkernel/intern/image.c
M	source/blender/imbuf/intern/bmp.c

===================================================================

diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index fe1f9097562..be354b04157 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -1345,6 +1345,7 @@ char BKE_imtype_valid_channels(const char imtype, bool write_file)
 
   /* bw */
   switch (imtype) {
+    case R_IMF_IMTYPE_BMP:
     case R_IMF_IMTYPE_PNG:
     case R_IMF_IMTYPE_JPEG90:
     case R_IMF_IMTYPE_TARGA:
diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c
index ae3ac624e3b..093b29b8939 100644
--- a/source/blender/imbuf/intern/bmp.c
+++ b/source/blender/imbuf/intern/bmp.c
@@ -306,8 +306,11 @@ int imb_savebmp(struct ImBuf *ibuf, const char *name, int flags)
 
   (void)flags; /* unused */
 
-  extrabytes = (4 - ibuf->x * 3 % 4) % 4;
-  bytesize = (ibuf->x * 3 + extrabytes) * ibuf->y;
+  const size_t bytes_per_pixel = (ibuf->planes + 7) >> 3;
+  BLI_assert(bytes_per_pixel == 1 || bytes_per_pixel == 3);
+
+  extrabytes = (4 - ibuf->x * bytes_per_pixel % 4) % 4;
+  bytesize = (ibuf->x * bytes_per_pixel + extrabytes) * ibuf->y;
 
   data = (uchar *)ibuf->rect;
   ofile = BLI_fopen(name, "wb");
@@ -315,17 +318,21 @@ int imb_savebmp(struct ImBuf *ibuf, const char *name, int flags)
     return 0;
   }
 
-  putShortLSB(19778, ofile);                                             /* "BM" */
-  putIntLSB(bytesize + BMP_FILEHEADER_SIZE + sizeof(infoheader), ofile); /* Total file size */
-  putShortLSB(0, ofile);                                                 /* Res1 */
-  putShortLSB(0, ofile);                                                 /* Res2 */
-  putIntLSB(BMP_FILEHEADER_SIZE + sizeof(infoheader), ofile);
+  const bool is_grayscale = bytes_per_pixel == 1;
+  const size_t palette_size = is_grayscale ? 255 * 4 : 0; /* RGBA32 */
+  const size_t pixel_array_start = BMP_FILEHEADER_SIZE + sizeof(infoheader) + palette_size;
+
+  putShortLSB(19778, ofile);                      /* "BM" */
+  putIntLSB(bytesize + pixel_array_start, ofile); /* Total file size */
+  putShortLSB(0, ofile);                          /* Res1 */
+  putShortLSB(0, ofile);                          /* Res2 */
+  putIntLSB(pixel_array_start, ofile);            /* offset to start of pixel array */
 
   putIntLSB(sizeof(infoheader), ofile);
   putIntLSB(ibuf->x, ofile);
   putIntLSB(ibuf->y, ofile);
   putShortLSB(1, ofile);
-  putShortLSB(24, ofile);
+  putShortLSB(is_grayscale ? 8 : 24, ofile);
   putIntLSB(0, ofile);
   putIntLSB(bytesize, ofile);
   putIntLSB((int)(ibuf->ppm[0] + 0.5), ofile);
@@ -333,24 +340,52 @@ int imb_savebmp(struct ImBuf *ibuf, const char *name, int flags)
   putIntLSB(0, ofile);
   putIntLSB(0, ofile);
 
-  /* Need to write out padded image data in bgr format */
-  for (size_t y = 0; y < ibuf->y; y++) {
-    for (size_t x = 0; x < ibuf->x; x++) {
-      ptr = (x + y * ibuf->x) * 4;
-      if (putc(data[ptr + 2], ofile) == EOF) {
-        return 0;
-      }
-      if (putc(data[ptr + 1], ofile) == EOF) {
-        return 0;
+  /* color palette table, which is just every grayscale color, full alpha */
+  if (is_grayscale) {
+    for (char i = 0; i < 255; i++) {
+      putc(i, ofile);
+      putc(i, ofile);
+      putc(i, ofile);
+      putc(0xFF, ofile);
+    }
+  }
+
+  if (is_grayscale) {
+    for (size_t y = 0; y < ibuf->y; y++) {
+      for (size_t x = 0; x < ibuf->x; x++) {
+        ptr = (x + y * ibuf->x) * 4;
+        if (putc(data[ptr], ofile) == EOF) {
+          return 0;
+        }
       }
-      if (putc(data[ptr], ofile) == EOF) {
-        return 0;
+      /* add padding here */
+      for (size_t t = 0; t < extrabytes; t++) {
+        if (putc(0, ofile) == EOF) {
+          return 0;
+        }
       }
     }
-    /* add padding here */
-    for (size_t t = 0; t < extrabytes; t++) {
-      if (putc(0, ofile) == EOF) {
-        return 0;
+  }
+  else {
+    /* Need to write out padded image data in bgr format */
+    for (size_t y = 0; y < ibuf->y; y++) {
+      for (size_t x = 0; x < ibuf->x; x++) {
+        ptr = (x + y * ibuf->x) * 4;
+        if (putc(data[ptr + 2], ofile) == EOF) {
+          return 0;
+        }
+        if (putc(data[ptr + 1], ofile) == EOF) {
+          return 0;
+        }
+        if (putc(data[ptr], ofile) == EOF) {
+          return 0;
+        }
+      }
+      /* add padding here */
+      for (size_t t = 0; t < extrabytes; t++) {
+        if (putc(0, ofile) == EOF) {
+          return 0;
+        }
       }
     }
   }



More information about the Bf-blender-cvs mailing list