plug-ins: more code cleanup in file-bmp

Use GLib endian macros in bmp-save.c
This commit is contained in:
Michael Natterer 2016-04-23 01:07:20 +02:00
parent e5a669bdfc
commit 785c104c69
3 changed files with 260 additions and 227 deletions

View File

@ -44,72 +44,71 @@
#endif #endif
static gint32 ReadImage (FILE *fd, static gint32 ReadImage (FILE *fd,
const gchar *filename, const gchar *filename,
gint width, gint width,
gint height, gint height,
guchar cmap[256][3], guchar cmap[256][3],
gint ncols, gint ncols,
gint bpp, gint bpp,
gint compression, gint compression,
gint rowbytes, gint rowbytes,
gboolean gray, gboolean gray,
const Bitmap_Channel *masks, const BitmapChannel *masks,
GError **error); GError **error);
static Bitmap_File_Head bitmap_file_head;
static Bitmap_Head bitmap_head;
static void static void
setMasksDefault (gushort biBitCnt, setMasksDefault (gushort biBitCnt,
Bitmap_Channel *masks) BitmapChannel *masks)
{ {
switch (biBitCnt) switch (biBitCnt)
{ {
case 32: case 32:
masks[0].mask = 0x00ff0000; masks[0].mask = 0x00ff0000;
masks[0].shiftin = 16; masks[0].shiftin = 16;
masks[0].max_value= (gfloat)255.0; masks[0].max_value = (gfloat)255.0;
masks[1].mask = 0x0000ff00; masks[1].mask = 0x0000ff00;
masks[1].shiftin = 8; masks[1].shiftin = 8;
masks[1].max_value= (gfloat)255.0; masks[1].max_value = (gfloat)255.0;
masks[2].mask = 0x000000ff; masks[2].mask = 0x000000ff;
masks[2].shiftin = 0; masks[2].shiftin = 0;
masks[2].max_value= (gfloat)255.0; masks[2].max_value = (gfloat)255.0;
masks[3].mask = 0x00000000; masks[3].mask = 0x00000000;
masks[3].shiftin = 0; masks[3].shiftin = 0;
masks[3].max_value= (gfloat)0.0; masks[3].max_value = (gfloat)0.0;
break; break;
case 24: case 24:
masks[0].mask = 0xff0000; masks[0].mask = 0xff0000;
masks[0].shiftin = 16; masks[0].shiftin = 16;
masks[0].max_value= (gfloat)255.0; masks[0].max_value = (gfloat)255.0;
masks[1].mask = 0x00ff00; masks[1].mask = 0x00ff00;
masks[1].shiftin = 8; masks[1].shiftin = 8;
masks[1].max_value= (gfloat)255.0; masks[1].max_value = (gfloat)255.0;
masks[2].mask = 0x0000ff; masks[2].mask = 0x0000ff;
masks[2].shiftin = 0; masks[2].shiftin = 0;
masks[2].max_value= (gfloat)255.0; masks[2].max_value = (gfloat)255.0;
masks[3].mask = 0x0; masks[3].mask = 0x0;
masks[3].shiftin = 0; masks[3].shiftin = 0;
masks[3].max_value= (gfloat)0.0; masks[3].max_value = (gfloat)0.0;
break; break;
case 16: case 16:
masks[0].mask = 0x7c00; masks[0].mask = 0x7c00;
masks[0].shiftin = 10; masks[0].shiftin = 10;
masks[0].max_value= (gfloat)31.0; masks[0].max_value = (gfloat)31.0;
masks[1].mask = 0x03e0; masks[1].mask = 0x03e0;
masks[1].shiftin = 5; masks[1].shiftin = 5;
masks[1].max_value= (gfloat)31.0; masks[1].max_value = (gfloat)31.0;
masks[2].mask = 0x001f; masks[2].mask = 0x001f;
masks[2].shiftin = 0; masks[2].shiftin = 0;
masks[2].max_value= (gfloat)31.0; masks[2].max_value = (gfloat)31.0;
masks[3].mask = 0x0; masks[3].mask = 0x0;
masks[3].shiftin = 0; masks[3].shiftin = 0;
masks[3].max_value= (gfloat)0.0; masks[3].max_value = (gfloat)0.0;
break; break;
default: default:
break; break;
} }
@ -134,13 +133,14 @@ ReadColorMap (FILE *fd,
gint size, gint size,
gboolean *gray) gboolean *gray)
{ {
gint i; gint i;
guchar rgb[4];
*gray = (number > 2); *gray = (number > 2);
for (i = 0; i < number ; i++) for (i = 0; i < number ; i++)
{ {
guchar rgb[4];
if (! ReadOK (fd, rgb, size)) if (! ReadOK (fd, rgb, size))
{ {
g_message (_("Bad colormap")); g_message (_("Bad colormap"));
@ -152,26 +152,30 @@ ReadColorMap (FILE *fd,
buffer[i][0] = rgb[2]; buffer[i][0] = rgb[2];
buffer[i][1] = rgb[1]; buffer[i][1] = rgb[1];
buffer[i][2] = rgb[0]; buffer[i][2] = rgb[0];
*gray = ((*gray) && (rgb[0]==rgb[1]) && (rgb[1]==rgb[2]));
*gray = ((*gray) && (rgb[0] == rgb[1]) && (rgb[1] == rgb[2]));
} }
return TRUE; return TRUE;
} }
static gboolean static gboolean
ReadChannelMasks (guint32 *tmp, ReadChannelMasks (guint32 *tmp,
Bitmap_Channel *masks, BitmapChannel *masks,
guint channels) guint channels)
{ {
guint32 mask; gint i;
gint i, nbits, offset, bit;
for (i = 0; i < channels; i++) for (i = 0; i < channels; i++)
{ {
guint32 mask;
gint nbits, offset, bit;
mask = tmp[i]; mask = tmp[i];
masks[i].mask = mask; masks[i].mask = mask;
nbits = 0; nbits = 0;
offset = -1; offset = -1;
for (bit = 0; bit < 32; bit++) for (bit = 0; bit < 32; bit++)
{ {
if (mask & 1) if (mask & 1)
@ -180,10 +184,12 @@ ReadChannelMasks (guint32 *tmp,
if (offset == -1) if (offset == -1)
offset = bit; offset = bit;
} }
mask = mask >> 1; mask = mask >> 1;
} }
masks[i].shiftin = offset;
masks[i].max_value = (gfloat)((1<<(nbits))-1); masks[i].shiftin = offset;
masks[i].max_value = (gfloat) ((1 << nbits) - 1);
#ifdef DEBUG #ifdef DEBUG
g_print ("Channel %d mask %08x in %d max_val %d\n", g_print ("Channel %d mask %08x in %d max_val %d\n",
@ -198,14 +204,16 @@ gint32
load_image (const gchar *filename, load_image (const gchar *filename,
GError **error) GError **error)
{ {
FILE *fd; FILE *fd;
guchar buffer[124]; BitmapFileHead bitmap_file_head;
gint ColormapSize, rowbytes, Maps; BitmapHead bitmap_head;
gboolean gray = FALSE; guchar buffer[124];
guchar ColorMap[256][3]; gint ColormapSize, rowbytes, Maps;
gint32 image_ID = -1; gboolean gray = FALSE;
gchar magick[2]; guchar ColorMap[256][3];
Bitmap_Channel masks[4]; gint32 image_ID = -1;
gchar magick[2];
BitmapChannel masks[4];
gimp_progress_init_printf (_("Opening '%s'"), gimp_progress_init_printf (_("Opening '%s'"),
gimp_filename_to_utf8 (filename)); gimp_filename_to_utf8 (filename));
@ -351,9 +359,9 @@ load_image (const gchar *filename,
goto out; goto out;
} }
bitmap_head.masks[0] = ToL(&buffer[0x00]); bitmap_head.masks[0] = ToL (&buffer[0x00]);
bitmap_head.masks[1] = ToL(&buffer[0x04]); bitmap_head.masks[1] = ToL (&buffer[0x04]);
bitmap_head.masks[2] = ToL(&buffer[0x08]); bitmap_head.masks[2] = ToL (&buffer[0x08]);
ReadChannelMasks (&bitmap_head.masks[0], masks, 3); ReadChannelMasks (&bitmap_head.masks[0], masks, 3);
} }
@ -370,7 +378,7 @@ load_image (const gchar *filename,
{ {
/* BI_ALPHABITFIELDS, etc. */ /* BI_ALPHABITFIELDS, etc. */
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("Unsupported compression (%lu) in BMP file from '%s'"), _("Unsupported compression (%u) in BMP file from '%s'"),
bitmap_head.biCompr, bitmap_head.biCompr,
gimp_filename_to_utf8 (filename)); gimp_filename_to_utf8 (filename));
} }
@ -392,20 +400,20 @@ load_image (const gchar *filename,
goto out; goto out;
} }
bitmap_head.biWidth =ToL (&buffer[0x00]); /* 12 */ bitmap_head.biWidth = ToL (&buffer[0x00]); /* 12 */
bitmap_head.biHeight =ToL (&buffer[0x04]); /* 16 */ bitmap_head.biHeight = ToL (&buffer[0x04]); /* 16 */
bitmap_head.biPlanes =ToS (&buffer[0x08]); /* 1A */ bitmap_head.biPlanes = ToS (&buffer[0x08]); /* 1A */
bitmap_head.biBitCnt =ToS (&buffer[0x0A]); /* 1C */ bitmap_head.biBitCnt = ToS (&buffer[0x0A]); /* 1C */
bitmap_head.biCompr =ToL (&buffer[0x0C]); /* 1E */ bitmap_head.biCompr = ToL (&buffer[0x0C]); /* 1E */
bitmap_head.biSizeIm =ToL (&buffer[0x10]); /* 22 */ bitmap_head.biSizeIm = ToL (&buffer[0x10]); /* 22 */
bitmap_head.biXPels =ToL (&buffer[0x14]); /* 26 */ bitmap_head.biXPels = ToL (&buffer[0x14]); /* 26 */
bitmap_head.biYPels =ToL (&buffer[0x18]); /* 2A */ bitmap_head.biYPels = ToL (&buffer[0x18]); /* 2A */
bitmap_head.biClrUsed =ToL (&buffer[0x1C]); /* 2E */ bitmap_head.biClrUsed = ToL (&buffer[0x1C]); /* 2E */
bitmap_head.biClrImp =ToL (&buffer[0x20]); /* 32 */ bitmap_head.biClrImp = ToL (&buffer[0x20]); /* 32 */
bitmap_head.masks[0] =ToL (&buffer[0x24]); /* 36 */ bitmap_head.masks[0] = ToL (&buffer[0x24]); /* 36 */
bitmap_head.masks[1] =ToL (&buffer[0x28]); /* 3A */ bitmap_head.masks[1] = ToL (&buffer[0x28]); /* 3A */
bitmap_head.masks[2] =ToL (&buffer[0x2C]); /* 3E */ bitmap_head.masks[2] = ToL (&buffer[0x2C]); /* 3E */
bitmap_head.masks[3] =ToL (&buffer[0x30]); /* 42 */ bitmap_head.masks[3] = ToL (&buffer[0x30]); /* 42 */
Maps = 4; Maps = 4;
ReadChannelMasks (&bitmap_head.masks[0], masks, 4); ReadChannelMasks (&bitmap_head.masks[0], masks, 4);
@ -554,7 +562,7 @@ load_image (const gchar *filename,
* word length (32 bits == 4 bytes) * word length (32 bits == 4 bytes)
*/ */
rowbytes= ((bitmap_head.biWidth * bitmap_head.biBitCnt - 1) / 32) * 4 + 4; rowbytes = ((bitmap_head.biWidth * bitmap_head.biBitCnt - 1) / 32) * 4 + 4;
#ifdef DEBUG #ifdef DEBUG
printf ("\nSize: %lu, Colors: %lu, Bits: %hu, Width: %ld, Height: %ld, " printf ("\nSize: %lu, Colors: %lu, Bits: %hu, Width: %ld, Height: %ld, "
@ -627,18 +635,18 @@ out:
} }
static gint32 static gint32
ReadImage (FILE *fd, ReadImage (FILE *fd,
const gchar *filename, const gchar *filename,
gint width, gint width,
gint height, gint height,
guchar cmap[256][3], guchar cmap[256][3],
gint ncols, gint ncols,
gint bpp, gint bpp,
gint compression, gint compression,
gint rowbytes, gint rowbytes,
gboolean gray, gboolean gray,
const Bitmap_Channel *masks, const BitmapChannel *masks,
GError **error) GError **error)
{ {
guchar v, n; guchar v, n;
gint xpos = 0; gint xpos = 0;
@ -749,6 +757,7 @@ ReadImage (FILE *fd,
while (ReadOK (fd, row_buf, rowbytes)) while (ReadOK (fd, row_buf, rowbytes))
{ {
temp = dest + (ypos * rowstride); temp = dest + (ypos * rowstride);
for (xpos= 0; xpos < width; ++xpos) for (xpos= 0; xpos < width; ++xpos)
{ {
px32 = ToL(&row_buf[xpos*4]); px32 = ToL(&row_buf[xpos*4]);
@ -758,9 +767,12 @@ ReadImage (FILE *fd,
if (channels > 3) if (channels > 3)
*(temp++) = ((px32 & masks[3].mask) >> masks[3].shiftin) * 255.0 / masks[3].max_value + 0.5; *(temp++) = ((px32 & masks[3].mask) >> masks[3].shiftin) * 255.0 / masks[3].max_value + 0.5;
} }
if (ypos == 0) if (ypos == 0)
break; break;
--ypos; /* next line */ --ypos; /* next line */
cur_progress++; cur_progress++;
if ((cur_progress % 5) == 0) if ((cur_progress % 5) == 0)
gimp_progress_update ((gdouble) cur_progress / gimp_progress_update ((gdouble) cur_progress /
@ -774,15 +786,19 @@ ReadImage (FILE *fd,
while (ReadOK (fd, row_buf, rowbytes)) while (ReadOK (fd, row_buf, rowbytes))
{ {
temp = dest + (ypos * rowstride); temp = dest + (ypos * rowstride);
for (xpos= 0; xpos < width; ++xpos) for (xpos= 0; xpos < width; ++xpos)
{ {
*(temp++) = row_buf[xpos * 3 + 2]; *(temp++) = row_buf[xpos * 3 + 2];
*(temp++) = row_buf[xpos * 3 + 1]; *(temp++) = row_buf[xpos * 3 + 1];
*(temp++) = row_buf[xpos * 3]; *(temp++) = row_buf[xpos * 3];
} }
if (ypos == 0) if (ypos == 0)
break; break;
--ypos; /* next line */ --ypos; /* next line */
cur_progress++; cur_progress++;
if ((cur_progress % 5) == 0) if ((cur_progress % 5) == 0)
gimp_progress_update ((gdouble) cur_progress / gimp_progress_update ((gdouble) cur_progress /
@ -796,6 +812,7 @@ ReadImage (FILE *fd,
while (ReadOK (fd, row_buf, rowbytes)) while (ReadOK (fd, row_buf, rowbytes))
{ {
temp = dest + (ypos * rowstride); temp = dest + (ypos * rowstride);
for (xpos= 0; xpos < width; ++xpos) for (xpos= 0; xpos < width; ++xpos)
{ {
rgb= ToS(&row_buf[xpos * 2]); rgb= ToS(&row_buf[xpos * 2]);
@ -805,9 +822,12 @@ ReadImage (FILE *fd,
if (channels > 3) if (channels > 3)
*(temp++) = ((rgb & masks[3].mask) >> masks[3].shiftin) * 255.0 / masks[3].max_value + 0.5; *(temp++) = ((rgb & masks[3].mask) >> masks[3].shiftin) * 255.0 / masks[3].max_value + 0.5;
} }
if (ypos == 0) if (ypos == 0)
break; break;
--ypos; /* next line */ --ypos; /* next line */
cur_progress++; cur_progress++;
if ((cur_progress % 5) == 0) if ((cur_progress % 5) == 0)
gimp_progress_update ((gdouble) cur_progress / gimp_progress_update ((gdouble) cur_progress /
@ -832,11 +852,14 @@ ReadImage (FILE *fd,
if (gray) if (gray)
*temp = cmap[*temp][0]; *temp = cmap[*temp][0];
} }
if (xpos == width) if (xpos == width)
{ {
fread (row_buf, rowbytes - 1 - (width * bpp - 1) / 8, 1, fd); fread (row_buf, rowbytes - 1 - (width * bpp - 1) / 8, 1, fd);
if (ypos == 0) if (ypos == 0)
break; break;
ypos--; ypos--;
xpos = 0; xpos = 0;
@ -845,6 +868,7 @@ ReadImage (FILE *fd,
gimp_progress_update ((gdouble) cur_progress / gimp_progress_update ((gdouble) cur_progress /
(gdouble) max_progress); (gdouble) max_progress);
} }
if (ypos < 0) if (ypos < 0)
break; break;
} }
@ -865,9 +889,9 @@ ReadImage (FILE *fd,
/* Count + Color - record */ /* Count + Color - record */
{ {
/* encoded mode run - /* encoded mode run -
row_buf[0] == run_length * row_buf[0] == run_length
row_buf[1] == pixel data * row_buf[1] == pixel data
*/ */
for (j = 0; for (j = 0;
((guchar) j < row_buf[0]) && (xpos < width);) ((guchar) j < row_buf[0]) && (xpos < width);)
{ {
@ -888,11 +912,13 @@ ReadImage (FILE *fd,
} }
} }
} }
if ((row_buf[0] == 0) && (row_buf[1] > 2)) if ((row_buf[0] == 0) && (row_buf[1] > 2))
/* uncompressed record */ /* uncompressed record */
{ {
n = row_buf[1]; n = row_buf[1];
total_bytes_read = 0; total_bytes_read = 0;
for (j = 0; j < n; j += (8 / bpp)) for (j = 0; j < n; j += (8 / bpp))
{ {
/* read the next byte in the record */ /* read the next byte in the record */
@ -901,6 +927,7 @@ ReadImage (FILE *fd,
g_message (_("The bitmap ends unexpectedly.")); g_message (_("The bitmap ends unexpectedly."));
break; break;
} }
total_bytes_read++; total_bytes_read++;
/* read all pixels from that byte */ /* read all pixels from that byte */
@ -925,8 +952,9 @@ ReadImage (FILE *fd,
/* absolute mode runs are padded to 16-bit alignment */ /* absolute mode runs are padded to 16-bit alignment */
if (total_bytes_read % 2) if (total_bytes_read % 2)
fread(&v, 1, 1, fd); fread (&v, 1, 1, fd);
} }
if ((row_buf[0] == 0) && (row_buf[1] == 0)) if ((row_buf[0] == 0) && (row_buf[1] == 0))
/* Line end */ /* Line end */
{ {
@ -938,11 +966,13 @@ ReadImage (FILE *fd,
gimp_progress_update ((gdouble) cur_progress / gimp_progress_update ((gdouble) cur_progress /
(gdouble) max_progress); (gdouble) max_progress);
} }
if ((row_buf[0] == 0) && (row_buf[1] == 1)) if ((row_buf[0] == 0) && (row_buf[1] == 1))
/* Bitmap end */ /* Bitmap end */
{ {
break; break;
} }
if ((row_buf[0] == 0) && (row_buf[1] == 2)) if ((row_buf[0] == 0) && (row_buf[1] == 2))
/* Deltarecord */ /* Deltarecord */
{ {
@ -951,6 +981,7 @@ ReadImage (FILE *fd,
g_message (_("The bitmap ends unexpectedly.")); g_message (_("The bitmap ends unexpectedly."));
break; break;
} }
xpos += row_buf[0]; xpos += row_buf[0];
ypos -= row_buf[1]; ypos -= row_buf[1];
} }

View File

@ -78,27 +78,6 @@ static struct
gint dont_write_color_space_data; gint dont_write_color_space_data;
} BMPSaveData; } BMPSaveData;
static Bitmap_File_Head bitmap_file_head;
static Bitmap_Head bitmap_head;
static void
FromL (gint32 wert,
guchar *bopuffer)
{
bopuffer[0] = (wert) & 0xff;
bopuffer[1] = (wert >> 0x08) & 0xff;
bopuffer[2] = (wert >> 0x10) & 0xff;
bopuffer[3] = (wert >> 0x18) & 0xff;
}
static void
FromS (gint16 wert,
guchar *bopuffer)
{
bopuffer[0] = (wert) & 0xff;
bopuffer[1] = (wert >> 0x08) & 0xff;
}
static void static void
write_color_map (FILE *f, write_color_map (FILE *f,
@ -151,25 +130,26 @@ save_image (const gchar *filename,
GimpRunMode run_mode, GimpRunMode run_mode,
GError **error) GError **error)
{ {
FILE *outfile; FILE *outfile;
gint Red[MAXCOLORS]; BitmapFileHead bitmap_file_head;
gint Green[MAXCOLORS]; BitmapHead bitmap_head;
gint Blue[MAXCOLORS]; gint Red[MAXCOLORS];
guchar *cmap; gint Green[MAXCOLORS];
gint rows, cols, Spcols, channels, MapSize, SpZeile; gint Blue[MAXCOLORS];
glong BitsPerPixel; guchar *cmap;
gint colors; gint rows, cols, Spcols, channels, MapSize, SpZeile;
guchar *pixels; glong BitsPerPixel;
GeglBuffer *buffer; gint colors;
const Babl *format; guchar *pixels;
GimpImageType drawable_type; GeglBuffer *buffer;
gint drawable_width; const Babl *format;
gint drawable_height; GimpImageType drawable_type;
guchar puffer[128]; gint drawable_width;
gint i; gint drawable_height;
gint mask_info_size; gint i;
gint color_space_size; gint mask_info_size;
guint32 Mask[4]; gint color_space_size;
guint32 Mask[4];
buffer = gimp_drawable_get_buffer (drawable_ID); buffer = gimp_drawable_get_buffer (drawable_ID);
@ -284,7 +264,8 @@ save_image (const gchar *filename,
if (! save_dialog (1)) if (! save_dialog (1))
return GIMP_PDB_CANCEL; return GIMP_PDB_CANCEL;
} }
else if ((BitsPerPixel == 24 || BitsPerPixel == 32)) else if (BitsPerPixel == 24 ||
BitsPerPixel == 32)
{ {
if (run_mode == GIMP_RUN_INTERACTIVE) if (run_mode == GIMP_RUN_INTERACTIVE)
{ {
@ -299,23 +280,23 @@ save_image (const gchar *filename,
BitsPerPixel = 24; BitsPerPixel = 24;
break; break;
case RGBA_8888: case RGBA_8888:
BitsPerPixel = 32; BitsPerPixel = 32;
mask_info_size = 16; mask_info_size = 16;
break; break;
case RGBX_8888: case RGBX_8888:
BitsPerPixel = 32; BitsPerPixel = 32;
mask_info_size = 16; mask_info_size = 16;
break; break;
case RGB_565: case RGB_565:
BitsPerPixel = 16; BitsPerPixel = 16;
mask_info_size = 16; mask_info_size = 16;
break; break;
case RGBA_5551: case RGBA_5551:
BitsPerPixel = 16; BitsPerPixel = 16;
mask_info_size = 16; mask_info_size = 16;
break; break;
case RGB_555: case RGB_555:
BitsPerPixel = 16; BitsPerPixel = 16;
mask_info_size = 16; mask_info_size = 16;
break; break;
default: default:
@ -449,26 +430,26 @@ save_image (const gchar *filename,
Write (outfile, "BM", 2); Write (outfile, "BM", 2);
FromL (bitmap_file_head.bfSize, &puffer[0x00]); bitmap_file_head.bfSize = GUINT32_TO_LE (bitmap_file_head.bfSize);
FromS (bitmap_file_head.zzHotX, &puffer[0x04]); bitmap_file_head.zzHotX = GUINT16_TO_LE (bitmap_file_head.zzHotX);
FromS (bitmap_file_head.zzHotY, &puffer[0x06]); bitmap_file_head.zzHotY = GUINT16_TO_LE (bitmap_file_head.zzHotY);
FromL (bitmap_file_head.bfOffs, &puffer[0x08]); bitmap_file_head.bfOffs = GUINT32_TO_LE (bitmap_file_head.bfOffs);
FromL (bitmap_file_head.biSize, &puffer[0x0C]); bitmap_file_head.biSize = GUINT32_TO_LE (bitmap_file_head.biSize);
Write (outfile, puffer, 16); Write (outfile, &bitmap_file_head.bfSize, 16);
FromL (bitmap_head.biWidth, &puffer[0x00]); bitmap_head.biWidth = GINT32_TO_LE (bitmap_head.biWidth);
FromL (bitmap_head.biHeight, &puffer[0x04]); bitmap_head.biHeight = GINT32_TO_LE (bitmap_head.biHeight);
FromS (bitmap_head.biPlanes, &puffer[0x08]); bitmap_head.biPlanes = GUINT16_TO_LE (bitmap_head.biPlanes);
FromS (bitmap_head.biBitCnt, &puffer[0x0A]); bitmap_head.biBitCnt = GUINT16_TO_LE (bitmap_head.biBitCnt);
FromL (bitmap_head.biCompr, &puffer[0x0C]); bitmap_head.biCompr = GUINT32_TO_LE (bitmap_head.biCompr);
FromL (bitmap_head.biSizeIm, &puffer[0x10]); bitmap_head.biSizeIm = GUINT32_TO_LE (bitmap_head.biSizeIm);
FromL (bitmap_head.biXPels, &puffer[0x14]); bitmap_head.biXPels = GUINT32_TO_LE (bitmap_head.biXPels);
FromL (bitmap_head.biYPels, &puffer[0x18]); bitmap_head.biYPels = GUINT32_TO_LE (bitmap_head.biYPels);
FromL (bitmap_head.biClrUsed, &puffer[0x1C]); bitmap_head.biClrUsed = GUINT32_TO_LE (bitmap_head.biClrUsed);
FromL (bitmap_head.biClrImp, &puffer[0x20]); bitmap_head.biClrImp = GUINT32_TO_LE (bitmap_head.biClrImp);
Write (outfile, puffer, 36); Write (outfile, &bitmap_head, 36);
if (mask_info_size > 0) if (mask_info_size > 0)
{ {
@ -512,46 +493,49 @@ save_image (const gchar *filename,
break; break;
} }
FromL (Mask[0], &puffer[0x00]); Mask[0] = GUINT32_TO_LE (Mask[0]);
FromL (Mask[1], &puffer[0x04]); Mask[1] = GUINT32_TO_LE (Mask[1]);
FromL (Mask[2], &puffer[0x08]); Mask[2] = GUINT32_TO_LE (Mask[2]);
FromL (Mask[3], &puffer[0x0C]); Mask[3] = GUINT32_TO_LE (Mask[3]);
Write (outfile, puffer, mask_info_size);
Write (outfile, &Mask, mask_info_size);
} }
if (! BMPSaveData.dont_write_color_space_data) if (! BMPSaveData.dont_write_color_space_data)
{ {
guint32 buf[0x11];
/* Write V5 color space fields */ /* Write V5 color space fields */
/* bV5CSType = LCS_sRGB */ /* bV5CSType = LCS_sRGB */
FromL (0x73524742, &puffer[0x00]); buf[0x00] = GUINT32_TO_LE (0x73524742);
/* bV5Endpoints is set to 0 (ignored) */ /* bV5Endpoints is set to 0 (ignored) */
for (i = 0; i < 0x24; i++) for (i = 0; i < 0x09; i++)
puffer[0x04 + i] = 0x00; buf[i + 1] = 0x00;
/* bV5GammaRed is set to 0 (ignored) */ /* bV5GammaRed is set to 0 (ignored) */
FromL (0x0, &puffer[0x28]); buf[0x0a] = GUINT32_TO_LE (0x0);
/* bV5GammaGreen is set to 0 (ignored) */ /* bV5GammaGreen is set to 0 (ignored) */
FromL (0x0, &puffer[0x2c]); buf[0x0b] = GUINT32_TO_LE (0x0);
/* bV5GammaBlue is set to 0 (ignored) */ /* bV5GammaBlue is set to 0 (ignored) */
FromL (0x0, &puffer[0x30]); buf[0x0c] = GUINT32_TO_LE (0x0);
/* bV5Intent = LCS_GM_GRAPHICS */ /* bV5Intent = LCS_GM_GRAPHICS */
FromL (0x00000002, &puffer[0x34]); buf[0x0d] = GUINT32_TO_LE (0x00000002);
/* bV5ProfileData is set to 0 (ignored) */ /* bV5ProfileData is set to 0 (ignored) */
FromL (0x0, &puffer[0x38]); buf[0x0e] = GUINT32_TO_LE (0x0);
/* bV5ProfileSize is set to 0 (ignored) */ /* bV5ProfileSize is set to 0 (ignored) */
FromL (0x0, &puffer[0x3c]); buf[0x0f] = GUINT32_TO_LE (0x0);
/* bV5Reserved = 0 */ /* bV5Reserved = 0 */
FromL (0x0, &puffer[0x40]); buf[0x10] = GUINT32_TO_LE (0x0);
Write (outfile, puffer, color_space_size); Write (outfile, buf, color_space_size);
} }
write_color_map (outfile, Red, Green, Blue, MapSize); write_color_map (outfile, Red, Green, Blue, MapSize);
@ -573,25 +557,38 @@ save_image (const gchar *filename,
return GIMP_PDB_SUCCESS; return GIMP_PDB_SUCCESS;
} }
static inline void Make565(guchar r, guchar g, guchar b, guchar *buf) static inline void
Make565 (guchar r,
guchar g,
guchar b,
guchar *buf)
{ {
gint p; gint p;
p = (((gint)(r / 255.0 * 31.0 + 0.5))<<11) |
(((gint)(g / 255.0 * 63.0 + 0.5))<<5) | p = ((((gint) (r / 255.0 * 31.0 + 0.5)) << 11) |
((gint)(b / 255.0 * 31.0 + 0.5)); (((gint) (g / 255.0 * 63.0 + 0.5)) << 5) |
buf[0] = (guchar)(p & 0xff); (((gint) (b / 255.0 * 31.0 + 0.5))));
buf[1] = (guchar)(p>>8);
buf[0] = (guchar) (p & 0xff);
buf[1] = (guchar) (p >> 8);
} }
static inline void Make5551(guchar r, guchar g, guchar b, guchar a, guchar *buf) static inline void
Make5551 (guchar r,
guchar g,
guchar b,
guchar a,
guchar *buf)
{ {
gint p; gint p;
p = (((gint)(r / 255.0 * 31.0 + 0.5))<<10) |
(((gint)(g / 255.0 * 31.0 + 0.5))<<5) | p = ((((gint) (r / 255.0 * 31.0 + 0.5)) << 10) |
((gint)(b / 255.0 * 31.0 + 0.5)) | (((gint) (g / 255.0 * 31.0 + 0.5)) << 5) |
((gint)(a / 255.0 + 0.5)<<15); (((gint) (b / 255.0 * 31.0 + 0.5))) |
buf[0] = (guchar)(p & 0xff); (((gint) (a / 255.0 + 0.5) << 15)));
buf[1] = (guchar)(p>>8);
buf[0] = (guchar) (p & 0xff);
buf[1] = (guchar) (p >> 8);
} }
static void static void
@ -609,7 +606,7 @@ write_image (FILE *f,
gint color_space_size) gint color_space_size)
{ {
guchar buf[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0 }; guchar buf[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0 };
guchar puffer[8]; guint32 uint32buf;
guchar *temp, v; guchar *temp, v;
guchar *row, *ketten; guchar *row, *ketten;
gint xpos, ypos, i, j, rowstride, length, thiswidth; gint xpos, ypos, i, j, rowstride, length, thiswidth;
@ -771,6 +768,7 @@ write_image (FILE *f,
breite = width / (8 / bpp); breite = width / (8 / bpp);
if (width % (8 / bpp)) if (width % (8 / bpp))
breite++; breite++;
/* then check for strings of equal bytes */ /* then check for strings of equal bytes */
for (i = 0; i < breite; i += j) for (i = 0; i < breite; i += j)
{ {
@ -844,6 +842,7 @@ write_image (FILE *f,
length += 2; length += 2;
} }
} }
Write (f, &buf[14], 2); /* End of row */ Write (f, &buf[14], 2); /* End of row */
length += 2; length += 2;
@ -852,16 +851,19 @@ write_image (FILE *f,
gimp_progress_update ((gdouble) cur_progress / gimp_progress_update ((gdouble) cur_progress /
(gdouble) max_progress); (gdouble) max_progress);
} }
fseek (f, -2, SEEK_CUR); /* Overwrite last End of row ... */ fseek (f, -2, SEEK_CUR); /* Overwrite last End of row ... */
Write (f, &buf[12], 2); /* ... with End of file */ Write (f, &buf[12], 2); /* ... with End of file */
fseek (f, 0x22, SEEK_SET); /* Write length of image */ fseek (f, 0x22, SEEK_SET); /* Write length of image */
FromL (length, puffer); uint32buf = GUINT32_TO_LE (length);
Write (f, puffer, 4); Write (f, &uint32buf, 4);
fseek (f, 0x02, SEEK_SET); /* Write length of file */ fseek (f, 0x02, SEEK_SET); /* Write length of file */
length += (0x36 + MapSize + mask_info_size + color_space_size); length += (0x36 + MapSize + mask_info_size + color_space_size);
FromL (length, puffer); uint32buf = GUINT32_TO_LE (length);
Write (f, puffer, 4); Write (f, &uint32buf, 4);
g_free (ketten); g_free (ketten);
g_free (row); g_free (row);
break; break;

View File

@ -34,37 +34,37 @@
#define WriteOK(file,buffer,len) (Write(buffer, len, file) != 0) #define WriteOK(file,buffer,len) (Write(buffer, len, file) != 0)
typedef struct _Bitmap_File_Head typedef struct
{ {
gchar zzMagic[2]; /* 00 "BM" */ gchar zzMagic[2]; /* 00 "BM" */
gulong bfSize; /* 02 */ guint32 bfSize; /* 02 */
gushort zzHotX; /* 06 */ guint16 zzHotX; /* 06 */
gushort zzHotY; /* 08 */ guint16 zzHotY; /* 08 */
gulong bfOffs; /* 0A */ guint32 bfOffs; /* 0A */
gulong biSize; /* 0E */ guint32 biSize; /* 0E */
} Bitmap_File_Head; } BitmapFileHead;
typedef struct _Bitmap_Head typedef struct
{ {
glong biWidth; /* 12 */ gint32 biWidth; /* 12 */
glong biHeight; /* 16 */ gint32 biHeight; /* 16 */
gushort biPlanes; /* 1A */ guint16 biPlanes; /* 1A */
gushort biBitCnt; /* 1C */ guint16 biBitCnt; /* 1C */
gulong biCompr; /* 1E */ guint32 biCompr; /* 1E */
gulong biSizeIm; /* 22 */ guint32 biSizeIm; /* 22 */
gulong biXPels; /* 26 */ guint32 biXPels; /* 26 */
gulong biYPels; /* 2A */ guint32 biYPels; /* 2A */
gulong biClrUsed; /* 2E */ guint32 biClrUsed; /* 2E */
gulong biClrImp; /* 32 */ guint32 biClrImp; /* 32 */
guint32 masks[4]; /* 36 */ guint32 masks[4]; /* 36 */
} Bitmap_Head; } BitmapHead;
typedef struct _Bitmap_Channel typedef struct
{ {
guint32 mask; guint32 mask;
guint32 shiftin; guint32 shiftin;
gfloat max_value; gfloat max_value;
} Bitmap_Channel; } BitmapChannel;
#endif /* __BMP_H__ */ #endif /* __BMP_H__ */