gimp/plug-ins/bmp/bmpread.c

558 lines
15 KiB
C
Raw Normal View History

1997-11-25 06:05:25 +08:00
/* bmpread.c reads any bitmap I could get for testing */
/* Alexander.Schulz@stud.uni-karlsruhe.de */
/*
* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* ----------------------------------------------------------------------------
*/
configure.in removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so * configure.in * Makefile.am: removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so you can easily skip those parts of the build * acinclude.m4 * config.sub * config.guess * ltconfig * ltmain.sh: libtool 1.3.2 * app/fileops.c: shuffle #includes to avoid warning about MIN and MAX [ The following is a big i18n patch from David Monniaux <david.monniaux@ens.fr> ] * tips/gimp_conseils.fr.txt * tips/gimp_tips.txt * tips/Makefile.am * configure.in: moved tips to separate dir * po-plugins: new dir for plug-in translation files * configure.in: add po-plugins dir and POTFILES processing * app/boundary.c * app/brightness_contrast.c * app/by_color_select.c * app/color_balance.c * app/convert.c * app/curves.c * app/free_select.c * app/gdisplay.c * app/gimpimage.c * app/gimpunit.c * app/gradient.c * app/gradient_select.c * app/install.c * app/session.c: various i18n tweaks * app/tips_dialog.c: localize tips filename * libgimp/gimpunit.c * libgimp/gimpunitmenu.c: #include "config.h" * plug-ins/CEL * plug-ins/CML_explorer * plug-ins/Lighting * plug-ins/apply_lens * plug-ins/autostretch_hsv * plug-ins/blur * plug-ins/bmp * plug-ins/borderaverage * plug-ins/bumpmap * plug-ins/bz2 * plug-ins/checkerboard * plug-ins/colorify * plug-ins/compose * plug-ins/convmatrix * plug-ins/cubism * plug-ins/depthmerge * plug-ins/destripe * plug-ins/gif * plug-ins/gifload * plug-ins/jpeg * plug-ins/mail * plug-ins/oilify * plug-ins/png * plug-ins/print * plug-ins/ps * plug-ins/xbm * plug-ins/xpm * plug-ins/xwd: plug-in i18n stuff -Yosh
1999-05-30 00:35:47 +08:00
#include "config.h"
1997-11-25 06:05:25 +08:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
1997-11-25 06:05:25 +08:00
#include <gtk/gtk.h>
#include <libgimp/gimp.h>
#include "bmp.h"
configure.in removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so * configure.in * Makefile.am: removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so you can easily skip those parts of the build * acinclude.m4 * config.sub * config.guess * ltconfig * ltmain.sh: libtool 1.3.2 * app/fileops.c: shuffle #includes to avoid warning about MIN and MAX [ The following is a big i18n patch from David Monniaux <david.monniaux@ens.fr> ] * tips/gimp_conseils.fr.txt * tips/gimp_tips.txt * tips/Makefile.am * configure.in: moved tips to separate dir * po-plugins: new dir for plug-in translation files * configure.in: add po-plugins dir and POTFILES processing * app/boundary.c * app/brightness_contrast.c * app/by_color_select.c * app/color_balance.c * app/convert.c * app/curves.c * app/free_select.c * app/gdisplay.c * app/gimpimage.c * app/gimpunit.c * app/gradient.c * app/gradient_select.c * app/install.c * app/session.c: various i18n tweaks * app/tips_dialog.c: localize tips filename * libgimp/gimpunit.c * libgimp/gimpunitmenu.c: #include "config.h" * plug-ins/CEL * plug-ins/CML_explorer * plug-ins/Lighting * plug-ins/apply_lens * plug-ins/autostretch_hsv * plug-ins/blur * plug-ins/bmp * plug-ins/borderaverage * plug-ins/bumpmap * plug-ins/bz2 * plug-ins/checkerboard * plug-ins/colorify * plug-ins/compose * plug-ins/convmatrix * plug-ins/cubism * plug-ins/depthmerge * plug-ins/destripe * plug-ins/gif * plug-ins/gifload * plug-ins/jpeg * plug-ins/mail * plug-ins/oilify * plug-ins/png * plug-ins/print * plug-ins/ps * plug-ins/xbm * plug-ins/xpm * plug-ins/xwd: plug-in i18n stuff -Yosh
1999-05-30 00:35:47 +08:00
#include "libgimp/stdplugins-intl.h"
1997-11-25 06:05:25 +08:00
gint32
ReadBMP (gchar *name)
1997-11-25 06:05:25 +08:00
{
FILE *fd;
gchar *temp_buf;
guchar buffer[64];
gint ColormapSize, rowbytes, Maps, Grey;
guchar ColorMap[256][3];
gint32 image_ID;
guchar magick[2];
1997-11-25 06:05:25 +08:00
1998-03-17 17:39:40 +08:00
if (interactive_bmp)
{
temp_buf = g_strdup_printf (_("Loading %s:"), name);
1998-03-17 17:39:40 +08:00
gimp_progress_init (temp_buf);
g_free (temp_buf);
}
1997-11-25 06:05:25 +08:00
filename = name;
fd = fopen (filename, "rb");
/* Is this a valid File? Should never be used because Gimp tests it. */
1997-11-25 06:05:25 +08:00
if (!fd)
{
g_message (_("%s: can't open \"%s\""), prog_name, filename);
1997-11-25 06:05:25 +08:00
return -1;
}
/* It is a File. Now is it a Bitmap? Read the shortest possible header */
if (!ReadOK(fd, magick, 2) || !(!strncmp(magick,"BA",2) ||
!strncmp(magick,"BM",2) || !strncmp(magick,"IC",2) ||
!strncmp(magick,"PI",2) || !strncmp(magick,"CI",2) ||
!strncmp(magick,"CP",2)))
{
g_message (_("%s: %s is not a valid BMP file"), prog_name, filename);
return -1;
}
1997-11-25 06:05:25 +08:00
while (!strncmp(magick,"BA",2))
{
if (!ReadOK(fd, buffer, 12))
{
g_message (_("%s: %s is not a valid BMP file"), prog_name, filename);
return -1;
}
if (!ReadOK(fd, magick, 2))
{
g_message (_("%s: %s is not a valid BMP file"), prog_name, filename);
return -1;
}
}
if (!ReadOK(fd, buffer, 12))
1997-11-25 06:05:25 +08:00
{
g_message (_("%s: %s is not a valid BMP file"), prog_name, filename);
1997-11-25 06:05:25 +08:00
return -1;
}
1998-03-17 17:39:40 +08:00
configure.in removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so * configure.in * Makefile.am: removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so you can easily skip those parts of the build * acinclude.m4 * config.sub * config.guess * ltconfig * ltmain.sh: libtool 1.3.2 * app/fileops.c: shuffle #includes to avoid warning about MIN and MAX [ The following is a big i18n patch from David Monniaux <david.monniaux@ens.fr> ] * tips/gimp_conseils.fr.txt * tips/gimp_tips.txt * tips/Makefile.am * configure.in: moved tips to separate dir * po-plugins: new dir for plug-in translation files * configure.in: add po-plugins dir and POTFILES processing * app/boundary.c * app/brightness_contrast.c * app/by_color_select.c * app/color_balance.c * app/convert.c * app/curves.c * app/free_select.c * app/gdisplay.c * app/gimpimage.c * app/gimpunit.c * app/gradient.c * app/gradient_select.c * app/install.c * app/session.c: various i18n tweaks * app/tips_dialog.c: localize tips filename * libgimp/gimpunit.c * libgimp/gimpunitmenu.c: #include "config.h" * plug-ins/CEL * plug-ins/CML_explorer * plug-ins/Lighting * plug-ins/apply_lens * plug-ins/autostretch_hsv * plug-ins/blur * plug-ins/bmp * plug-ins/borderaverage * plug-ins/bumpmap * plug-ins/bz2 * plug-ins/checkerboard * plug-ins/colorify * plug-ins/compose * plug-ins/convmatrix * plug-ins/cubism * plug-ins/depthmerge * plug-ins/destripe * plug-ins/gif * plug-ins/gifload * plug-ins/jpeg * plug-ins/mail * plug-ins/oilify * plug-ins/png * plug-ins/print * plug-ins/ps * plug-ins/xbm * plug-ins/xpm * plug-ins/xwd: plug-in i18n stuff -Yosh
1999-05-30 00:35:47 +08:00
/* bring them to the right byteorder. Not too nice, but it should work */
1998-03-17 17:39:40 +08:00
Bitmap_File_Head.bfSize = ToL (&buffer[0x00]);
Bitmap_File_Head.zzHotX = ToS (&buffer[0x04]);
Bitmap_File_Head.zzHotY = ToS (&buffer[0x06]);
Bitmap_File_Head.bfOffs = ToL (&buffer[0x08]);
if (!ReadOK(fd, buffer, 4))
{
g_message(_("%s: %s is not a valid BMP file"), prog_name, filename);
return -1;
}
Bitmap_File_Head.biSize = ToL (&buffer[0x00]);
1997-11-25 06:05:25 +08:00
/* What kind of bitmap is it? */
1997-11-25 06:05:25 +08:00
if (Bitmap_File_Head.biSize == 12) /* OS/2 1.x ? */
2000-03-25 03:25:47 +08:00
{
if (!ReadOK (fd, buffer, 8))
2000-03-25 03:25:47 +08:00
{
g_message (_("%s: error reading BMP file header"), prog_name);
2000-03-25 03:25:47 +08:00
return -1;
}
Bitmap_Head.biWidth =ToS (&buffer[0x00]); /* 12 */
Bitmap_Head.biHeight =ToS (&buffer[0x02]); /* 14 */
Bitmap_Head.biPlanes =ToS (&buffer[0x04]); /* 16 */
Bitmap_Head.biBitCnt =ToS (&buffer[0x06]); /* 18 */
2000-05-12 14:53:15 +08:00
Bitmap_Head.biCompr = 0;
Bitmap_Head.biSizeIm = 0;
Bitmap_Head.biXPels = Bitmap_Head.biYPels = 0;
Bitmap_Head.biClrUsed = 0;
2000-03-25 03:25:47 +08:00
Maps = 3;
}
else if (Bitmap_File_Head.biSize == 40) /* Windows 3.x */
1997-11-25 06:05:25 +08:00
{
if (!ReadOK (fd, buffer, Bitmap_File_Head.biSize - 4))
1997-11-25 06:05:25 +08:00
{
g_message (_("%s: error reading BMP file header"), prog_name);
1997-11-25 06:05:25 +08:00
return -1;
}
Bitmap_Head.biWidth =ToL (&buffer[0x00]); /* 12 */
Bitmap_Head.biHeight =ToL (&buffer[0x04]); /* 16 */
Bitmap_Head.biPlanes =ToS (&buffer[0x08]); /* 1A */
Bitmap_Head.biBitCnt =ToS (&buffer[0x0A]); /* 1C */
Bitmap_Head.biCompr =ToL (&buffer[0x0C]); /* 1E */
Bitmap_Head.biSizeIm =ToL (&buffer[0x10]); /* 22 */
Bitmap_Head.biXPels =ToL (&buffer[0x14]); /* 26 */
Bitmap_Head.biYPels =ToL (&buffer[0x18]); /* 2A */
Bitmap_Head.biClrUsed =ToL (&buffer[0x1C]); /* 2E */
Bitmap_Head.biClrImp =ToL (&buffer[0x20]); /* 32 */
/* 36 */
Maps = 4;
1997-11-25 06:05:25 +08:00
}
else if (Bitmap_File_Head.biSize <= 64) /* Probably OS/2 2.x */
1997-11-25 06:05:25 +08:00
{
if (!ReadOK (fd, buffer, Bitmap_File_Head.biSize - 4))
1997-11-25 06:05:25 +08:00
{
g_message (_("%s: error reading BMP file header"), prog_name);
1997-11-25 06:05:25 +08:00
return -1;
}
Bitmap_Head.biWidth =ToL (&buffer[0x00]); /* 12 */
Bitmap_Head.biHeight =ToL (&buffer[0x04]); /* 16 */
Bitmap_Head.biPlanes =ToS (&buffer[0x08]); /* 1A */
Bitmap_Head.biBitCnt =ToS (&buffer[0x0A]); /* 1C */
Bitmap_Head.biCompr =ToL (&buffer[0x0C]); /* 1E */
Bitmap_Head.biSizeIm =ToL (&buffer[0x10]); /* 22 */
Bitmap_Head.biXPels =ToL (&buffer[0x14]); /* 26 */
Bitmap_Head.biYPels =ToL (&buffer[0x18]); /* 2A */
Bitmap_Head.biClrUsed =ToL (&buffer[0x1C]); /* 2E */
Bitmap_Head.biClrImp =ToL (&buffer[0x20]); /* 32 */
/* 36 */
Maps = 3;
1997-11-25 06:05:25 +08:00
}
else
{
g_message (_("%s: error reading BMP file header"), prog_name);
return -1;
}
1997-11-25 06:05:25 +08:00
2000-05-12 14:53:15 +08:00
/* Valid bitpdepthis 1, 4, 8, 16, 24, 32 */
/* 16 is awful, we should probably shoot whoever invented it */
1997-11-25 06:05:25 +08:00
/* There should be some colors used! */
ColormapSize = (Bitmap_File_Head.bfOffs - Bitmap_File_Head.biSize - 14) / Maps;
if ((Bitmap_Head.biClrUsed == 0) && (Bitmap_Head.biBitCnt <= 8))
ColormapSize = Bitmap_Head.biClrUsed = 1 << Bitmap_Head.biBitCnt;
2000-05-12 14:53:15 +08:00
/* Sanity checks */
if (Bitmap_Head.biHeight == 0 || Bitmap_Head.biWidth == 0) {
g_message (_("%s: error reading BMP file header"), prog_name);
return -1;
}
if (Bitmap_Head.biPlanes != 1) {
g_message (_("%s: error reading BMP file header"), prog_name);
return -1;
}
if (ColormapSize > 256 || Bitmap_Head.biClrUsed > 256) {
g_message (_("%s: error reading BMP file header"), prog_name);
return -1;
}
/* Windows and OS/2 declare filler so that rows are a multiple of
* word length (32 bits == 4 bytes)
*/
2000-05-12 14:53:15 +08:00
rowbytes= ( (Bitmap_Head.biWidth * Bitmap_Head.biBitCnt - 1) / 32) * 4 + 4;
1997-11-25 06:05:25 +08:00
#ifdef DEBUG
printf("\nSize: %u, Colors: %u, Bits: %u, Width: %u, Height: %u, Comp: %u, Zeile: %u\n",
1998-03-17 17:39:40 +08:00
Bitmap_File_Head.bfSize,Bitmap_Head.biClrUsed,Bitmap_Head.biBitCnt,Bitmap_Head.biWidth,
Bitmap_Head.biHeight, Bitmap_Head.biCompr, rowbytes);
1997-11-25 06:05:25 +08:00
#endif
/* Get the Colormap */
if (ReadColorMap (fd, ColorMap, ColormapSize, Maps, &Grey) == -1)
return -1;
1997-11-25 06:05:25 +08:00
#ifdef DEBUG
printf("Colormap read\n");
#endif
fseek(fd, Bitmap_File_Head.bfOffs, SEEK_SET);
1997-11-25 06:05:25 +08:00
/* Get the Image and return the ID or -1 on error*/
image_ID = ReadImage (fd,
Bitmap_Head.biWidth,
Bitmap_Head.biHeight,
ColorMap,
Bitmap_Head.biClrUsed,
Bitmap_Head.biBitCnt,
Bitmap_Head.biCompr,
rowbytes,
Grey);
if (Bitmap_Head.biXPels > 0 && Bitmap_Head.biYPels > 0)
{
/* Fixed up from scott@asofyet's changes last year, njl195 */
gdouble xresolution;
gdouble yresolution;
1997-11-25 06:05:25 +08:00
/* I don't agree with scott's feeling that Gimp should be
* trying to "fix" metric resolution translations, in the
* long term Gimp should be SI (metric) anyway, but we
* haven't told the Americans that yet */
xresolution = Bitmap_Head.biXPels * 0.0254;
yresolution = Bitmap_Head.biYPels * 0.0254;
gimp_image_set_resolution (image_ID, xresolution, yresolution);
}
1997-11-25 06:05:25 +08:00
return (image_ID);
1997-11-25 06:05:25 +08:00
}
gint
ReadColorMap (FILE *fd,
guchar buffer[256][3],
gint number,
gint size,
gint *grey)
1997-11-25 06:05:25 +08:00
{
gint i;
guchar rgb[4];
1997-11-25 06:05:25 +08:00
*grey=(number>2);
for (i = 0; i < number ; i++)
{
if (!ReadOK (fd, rgb, size))
{
g_message (_("%s: bad colormap"), prog_name);
1997-11-25 06:05:25 +08:00
return -1;
}
/* Bitmap save the colors in another order! But change only once! */
buffer[i][0] = rgb[2];
buffer[i][1] = rgb[1];
buffer[i][2] = rgb[0];
*grey = ((*grey) && (rgb[0]==rgb[1]) && (rgb[1]==rgb[2]));
1997-11-25 06:05:25 +08:00
}
return 0;
1997-11-25 06:05:25 +08:00
}
Image
ReadImage (FILE *fd,
gint width,
gint height,
guchar cmap[256][3],
gint ncols,
gint bpp,
gint compression,
2000-05-12 14:53:15 +08:00
gint rowbytes,
gint grey)
1997-11-25 06:05:25 +08:00
{
guchar v,wieviel;
GimpPixelRgn pixel_rgn;
gint xpos = 0, ypos = 0;
1997-11-25 06:05:25 +08:00
Image image;
gint32 layer;
GimpDrawable *drawable;
guchar *dest, *temp, *buffer;
1997-11-25 06:05:25 +08:00
guchar gimp_cmap[768];
gushort rgb;
1997-11-25 06:05:25 +08:00
long rowstride, channels;
2000-05-17 03:00:55 +08:00
gint i, j, cur_progress, max_progress, unused;
1997-11-25 06:05:25 +08:00
/* Make a new image in the gimp */
if (bpp >= 16)
{
image = gimp_image_new (width, height, GIMP_RGB);
layer = gimp_layer_new (image, _("Background"),
width, height, GIMP_RGB_IMAGE, 100, GIMP_NORMAL_MODE);
channels = 3;
}
else if (grey)
1997-11-25 06:05:25 +08:00
{
image = gimp_image_new (width, height, GIMP_GRAY);
layer = gimp_layer_new (image, _("Background"),
width, height, GIMP_GRAY_IMAGE, 100, GIMP_NORMAL_MODE);
1998-03-17 17:39:40 +08:00
channels = 1;
1997-11-25 06:05:25 +08:00
}
else
1997-11-25 06:05:25 +08:00
{
image = gimp_image_new (width, height, GIMP_INDEXED);
layer = gimp_layer_new (image, _("Background"),
width, height, GIMP_INDEXED_IMAGE, 100, GIMP_NORMAL_MODE);
channels = 1;
1997-11-25 06:05:25 +08:00
}
2000-05-12 14:53:15 +08:00
gimp_image_set_filename(image, filename);
1997-11-25 06:05:25 +08:00
gimp_image_add_layer(image,layer,0);
drawable = gimp_drawable_get(layer);
1998-03-17 17:39:40 +08:00
1997-11-25 06:05:25 +08:00
dest = g_malloc(drawable->width*drawable->height*channels);
2000-05-12 14:53:15 +08:00
buffer= g_malloc(rowbytes);
1997-11-25 06:05:25 +08:00
rowstride = drawable->width * channels;
ypos = height - 1; /* Bitmaps begin in the lower left corner */
1997-11-25 06:05:25 +08:00
cur_progress = 0;
max_progress = height;
2000-05-12 14:53:15 +08:00
1997-11-25 06:05:25 +08:00
2000-05-12 14:53:15 +08:00
switch (bpp) {
case 32:
{
2000-05-12 14:53:15 +08:00
while (ReadOK (fd, buffer, rowbytes))
{
temp = dest + (ypos * rowstride);
for (xpos= 0; xpos < width; ++xpos)
{
*(temp++)= buffer[xpos * 4 + 2];
*(temp++)= buffer[xpos * 4 + 1];
*(temp++)= buffer[xpos * 4];
}
--ypos; /* next line */
2000-05-12 14:53:15 +08:00
cur_progress++;
if ((interactive_bmp) && ((cur_progress % 5) == 0))
gimp_progress_update ((gdouble) cur_progress /
(gdouble) max_progress);
}
}
2000-05-12 14:53:15 +08:00
break;
case 24:
1997-11-25 06:05:25 +08:00
{
2000-05-12 14:53:15 +08:00
while (ReadOK (fd, buffer, rowbytes))
1997-11-25 06:05:25 +08:00
{
2000-05-12 14:53:15 +08:00
temp = dest + (ypos * rowstride);
for (xpos= 0; xpos < width; ++xpos)
1997-11-25 06:05:25 +08:00
{
2000-05-12 14:53:15 +08:00
*(temp++)= buffer[xpos * 3 + 2];
*(temp++)= buffer[xpos * 3 + 1];
*(temp++)= buffer[xpos * 3];
}
--ypos; /* next line */
cur_progress++;
if ((interactive_bmp) && ((cur_progress % 5) == 0))
gimp_progress_update ((gdouble) cur_progress /
(gdouble) max_progress);
1997-11-25 06:05:25 +08:00
}
}
2000-05-12 14:53:15 +08:00
break;
case 16:
{
2000-05-12 14:53:15 +08:00
while (ReadOK (fd, buffer, rowbytes))
{
temp = dest + (ypos * rowstride);
for (xpos= 0; xpos < width; ++xpos)
{
rgb= ToS(&buffer[xpos * 2]);
*(temp++)= ((rgb >> 10) & 0x1f) * 8;
*(temp++)= ((rgb >> 5) & 0x1f) * 8;
*(temp++)= ((rgb) & 0x1f) * 8;
}
--ypos; /* next line */
2000-05-12 14:53:15 +08:00
cur_progress++;
if ((interactive_bmp) && ((cur_progress % 5) == 0))
gimp_progress_update ((gdouble) cur_progress /
(gdouble) max_progress);
}
}
2000-05-12 14:53:15 +08:00
break;
case 8:
case 4:
case 1:
1997-11-25 06:05:25 +08:00
{
2000-05-12 14:53:15 +08:00
if (compression == 0)
1998-03-17 17:39:40 +08:00
{
while (ReadOK (fd, &v, 1))
{
for (i = 1; (i <= (8 / bpp)) && (xpos < width); i++, xpos++)
{
temp = dest + (ypos * rowstride) + (xpos * channels);
*temp=( v & ( ((1<<bpp)-1) << (8-(i*bpp)) ) ) >> (8-(i*bpp));
if (grey)
*temp = cmap[*temp][0];
}
if (xpos == width)
{
2000-05-17 03:00:55 +08:00
unused = ReadOK (fd, buffer, rowbytes - 1 -
2000-05-12 14:53:15 +08:00
(width * bpp - 1) / 8);
ypos--;
xpos = 0;
cur_progress++;
if ((interactive_bmp) &&
((cur_progress % 5) == 0))
gimp_progress_update ((gdouble) cur_progress /
(gdouble) max_progress);
}
if (ypos < 0)
break;
}
break;
1998-03-17 17:39:40 +08:00
}
2000-05-12 14:53:15 +08:00
else
1998-03-17 17:39:40 +08:00
{
2000-05-12 14:53:15 +08:00
while (ypos >= 0 && xpos <= width)
1998-03-17 17:39:40 +08:00
{
2000-05-17 03:00:55 +08:00
unused = ReadOK (fd, buffer, 2);
2000-05-12 14:53:15 +08:00
if ((guchar) buffer[0] != 0)
/* Count + Color - record */
1998-03-17 17:39:40 +08:00
{
2000-05-12 14:53:15 +08:00
for (j = 0; ((guchar) j < (guchar) buffer[0]) && (xpos < width);)
{
1998-03-17 17:39:40 +08:00
#ifdef DEBUG2
printf("%u %u | ",xpos,width);
1998-03-17 17:39:40 +08:00
#endif
for (i = 1;
((i <= (8 / bpp)) &&
(xpos < width) &&
2000-05-12 14:53:15 +08:00
((guchar) j < (unsigned char) buffer[0]));
i++, xpos++, j++)
{
temp = dest + (ypos * rowstride) + (xpos * channels);
2000-05-12 14:53:15 +08:00
*temp = (buffer[1] & (((1<<bpp)-1) << (8 - (i * bpp)))) >> (8 - (i * bpp));
if (grey)
*temp = cmap[*temp][0];
}
1998-03-17 17:39:40 +08:00
}
}
2000-05-12 14:53:15 +08:00
if (((guchar) buffer[0] == 0) && ((guchar) buffer[1] > 2))
/* uncompressed record */
1998-03-17 17:39:40 +08:00
{
2000-05-12 14:53:15 +08:00
wieviel = buffer[1];
for (j = 0; j < wieviel; j += (8 / bpp))
1998-03-17 17:39:40 +08:00
{
2000-05-17 03:00:55 +08:00
unused = ReadOK (fd, &v, 1);
i = 1;
while ((i <= (8 / bpp)) && (xpos < width))
{
temp = dest + (ypos * rowstride) + (xpos * channels);
*temp = (v & (((1<<bpp)-1) << (8-(i*bpp)))) >> (8-(i*bpp));
if (grey)
*temp = cmap[*temp][0];
i++;
xpos++;
}
1998-03-17 17:39:40 +08:00
}
if ((wieviel % 2) && (bpp==4))
wieviel++;
if ((wieviel / (8 / bpp)) % 2)
2000-05-17 03:00:55 +08:00
unused = ReadOK (fd, &v, 1);
/*if odd(x div (8 div bpp )) then blockread(f,z^,1);*/
}
2000-05-12 14:53:15 +08:00
if (((guchar) buffer[0] == 0) && ((guchar) buffer[1]==0))
2000-05-17 03:00:55 +08:00
/* Line end */
{
ypos--;
xpos = 0;
cur_progress++;
if ((interactive_bmp) &&
((cur_progress % 5) == 0))
gimp_progress_update ((gdouble) cur_progress /
(gdouble) max_progress);
}
2000-05-12 14:53:15 +08:00
if (((guchar) buffer[0]==0) && ((guchar) buffer[1]==1))
2000-05-17 03:00:55 +08:00
/* Bitmap end */
{
break;
}
2000-05-12 14:53:15 +08:00
if (((guchar) buffer[0]==0) && ((guchar) buffer[1]==2))
/* Deltarecord */
{
2000-05-17 03:00:55 +08:00
unused = ReadOK (fd, buffer, 2);
2000-05-12 14:53:15 +08:00
xpos += (guchar) buffer[0];
ypos -= (guchar) buffer[1];
1998-03-17 17:39:40 +08:00
}
}
break;
1998-03-17 17:39:40 +08:00
}
}
2000-05-12 14:53:15 +08:00
break;
default:
/* This is very bad, we should not be here */
2000-05-17 03:00:55 +08:00
;
2000-05-12 14:53:15 +08:00
}
fclose (fd);
if (bpp <= 8)
for (i = 0, j = 0; i < ncols; i++)
{
gimp_cmap[j++] = cmap[i][0];
gimp_cmap[j++] = cmap[i][1];
gimp_cmap[j++] = cmap[i][2];
}
if (interactive_bmp)
gimp_progress_update (1);
gimp_pixel_rgn_init (&pixel_rgn, drawable,
0, 0, drawable->width, drawable->height, TRUE, FALSE);
gimp_pixel_rgn_set_rect (&pixel_rgn, dest,
0, 0, drawable->width, drawable->height);
if ((!grey) && (bpp<= 8))
gimp_image_set_cmap (image, gimp_cmap, ncols);
gimp_drawable_flush (drawable);
gimp_drawable_detach (drawable);
g_free (dest);
return image;
1997-11-25 06:05:25 +08:00
}