Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Fulop <Yam>2020-01-29 04:37:14 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-01-29 04:40:49 +0300
commitd8435596d5af76537137a7d3f40afce271223095 (patch)
tree5da61f5ae73ef3c1ea011ea0319486b425a53f1e /source/blender/imbuf
parent7642ee627ad86316df93541c4975c6c9ef23883b (diff)
imbuf: support writing grayscale BMP images
Diffstat (limited to 'source/blender/imbuf')
-rw-r--r--source/blender/imbuf/intern/bmp.c81
1 files changed, 58 insertions, 23 deletions
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;
+ }
}
}
}