summaryrefslogtreecommitdiff
path: root/graphics/sam2p/input-bmp.ci
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/sam2p/input-bmp.ci')
-rw-r--r--graphics/sam2p/input-bmp.ci484
1 files changed, 484 insertions, 0 deletions
diff --git a/graphics/sam2p/input-bmp.ci b/graphics/sam2p/input-bmp.ci
new file mode 100644
index 0000000000..234626d375
--- /dev/null
+++ b/graphics/sam2p/input-bmp.ci
@@ -0,0 +1,484 @@
+/* This code is ripped from Autotrace-0.29. Small modifications by pts. */
+
+/* input-bmp.ci: reads any bitmap I could get for testing */
+
+#ifdef __GNUC__
+#ifndef __clang__
+#pragma implementation
+#endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* #include "types.h" */
+#include "at_bitmap.h"
+/* #include "message.h" */
+/* #include "xstd.h" */
+/* #include "input-bmp.h" */
+
+#define MAXCOLORS 256
+/* #define Image long */
+
+#define BitSet(byte, bit) (((byte) & (bit)) == (bit))
+
+#define ReadOK(file,buffer,len) (fread(buffer, len, 1, file) != 0)
+
+struct Bitmap_File_Head_Struct
+{
+ char zzMagic[2]; /* 00 "BM" */
+ unsigned long bfSize; /* 02 */
+ unsigned short zzHotX; /* 06 */
+ unsigned short zzHotY; /* 08 */
+ unsigned long bfOffs; /* 0A */
+ unsigned long biSize; /* 0E */
+} Bitmap_File_Head;
+
+struct Bitmap_Head_Struct
+{
+ unsigned long biWidth; /* 12 */
+ unsigned long biHeight; /* 16 */
+ unsigned short biPlanes; /* 1A */
+ unsigned short biBitCnt; /* 1C */
+ unsigned long biCompr; /* 1E */
+ unsigned long biSizeIm; /* 22 */
+ unsigned long biXPels; /* 26 */
+ unsigned long biYPels; /* 2A */
+ unsigned long biClrUsed; /* 2E */
+ unsigned long biClrImp; /* 32 */
+ /* 36 */
+} Bitmap_Head;
+
+static long ToL (unsigned char *);
+static short ToS (unsigned char *);
+static int ReadColorMap (FILE *,
+ unsigned char[256][3],
+ int,
+ int,
+ int *);
+static unsigned char *ReadImage (FILE *,
+ int,
+ int,
+ unsigned char[256][3],
+ int,
+ int,
+ int,
+ int);
+
+#if PTS_SAM2P
+bitmap_type bmp_load_image (FILE* filename)
+#else
+bitmap_type bmp_load_image (at_string filename)
+#endif
+{
+ FILE *fd;
+ unsigned char buffer[64];
+ int ColormapSize, rowbytes, Maps=0, Grey;
+ unsigned char ColorMap[256][3];
+ bitmap_type image;
+
+ #if PTS_SAM2P /**** pts ****/
+ fd=filename;
+ #else
+ fd = fopen (filename, "rb");
+
+ if (!fd)
+ FATAL1 ("Can't open \"%s\"\n", filename);
+ #endif
+
+ /* It is a File. Now is it a Bitmap? Read the shortest possible header.*/
+
+ if (!ReadOK(fd, buffer, 18) || (strncmp((const char *)buffer,"BM",2)))
+ #if PTS_SAM2P /**** pts ****/
+ FATALP ("BMP: Not a valid BMP file");
+ #else
+ FATAL ("Not a valid BMP file %s\n");
+ #endif
+
+ /* bring them to the right byteorder. Not too nice, but it should work */
+
+ Bitmap_File_Head.bfSize = ToL (&buffer[0x02]);
+ Bitmap_File_Head.zzHotX = ToS (&buffer[0x06]);
+ Bitmap_File_Head.zzHotY = ToS (&buffer[0x08]);
+ Bitmap_File_Head.bfOffs = ToL (&buffer[0x0a]);
+ Bitmap_File_Head.biSize = ToL (&buffer[0x0e]);
+
+ /* What kind of bitmap is it? */
+
+ if (Bitmap_File_Head.biSize == 12) /* OS/2 1.x ? */
+ {
+ if (!ReadOK (fd, buffer, 8))
+ FATALP ("BMP: Error reading BMP file header #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 */
+ Bitmap_Head.biCompr = 0;
+ Bitmap_Head.biSizeIm = 0;
+ Bitmap_Head.biXPels = Bitmap_Head.biYPels = 0;
+ Bitmap_Head.biClrUsed = 0;
+ Maps = 3;
+ }
+ else if (Bitmap_File_Head.biSize == 40) /* Windows 3.x */
+ {
+ if (!ReadOK (fd, buffer, Bitmap_File_Head.biSize - 4))
+ FATALP ("BMP: Error reading BMP file header #2");
+
+ 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;
+ }
+ else if (Bitmap_File_Head.biSize <= 64) /* Probably OS/2 2.x */
+ {
+ if (!ReadOK (fd, buffer, Bitmap_File_Head.biSize - 4))
+ FATALP ("BMP: Error reading BMP file header #3");
+
+ 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;
+ }
+ else
+ FATALP ("BMP: Error reading BMP file header #4");
+
+ /* Valid options 1, 4, 8, 16, 24, 32 */
+ /* 16 is awful, we should probably shoot whoever invented it */
+
+ /* 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))
+ Bitmap_Head.biClrUsed = ColormapSize;
+
+ /* Sanity checks */
+
+ if (Bitmap_Head.biHeight == 0 || Bitmap_Head.biWidth == 0)
+ FATALP ("BMP: Error reading BMP file header #5");
+
+ if (Bitmap_Head.biPlanes != 1)
+ FATALP ("BMP: Error reading BMP file header #6");
+
+ if (ColormapSize > 256 || Bitmap_Head.biClrUsed > 256)
+ FATALP ("BMP: Error reading BMP file header #7");
+
+ /* Windows and OS/2 declare filler so that rows are a multiple of
+ * word length (32 bits == 4 bytes)
+ */
+
+ rowbytes= ( (Bitmap_Head.biWidth * Bitmap_Head.biBitCnt - 1) / 32) * 4 + 4;
+
+#ifdef DEBUG
+ printf("\nSize: %u, Colors: %u, Bits: %u, Width: %u, Height: %u, Comp: %u, Zeile: %u\n",
+ Bitmap_File_Head.bfSize,Bitmap_Head.biClrUsed,Bitmap_Head.biBitCnt,Bitmap_Head.biWidth,
+ Bitmap_Head.biHeight, Bitmap_Head.biCompr, rowbytes);
+#endif
+
+ /* Get the Colormap */
+
+ if (ReadColorMap (fd, ColorMap, ColormapSize, Maps, &Grey) == -1)
+ FATALP ("BMP: Cannot read the colormap");
+
+#ifdef DEBUG
+ printf("Colormap read\n");
+#endif
+
+ /* Get the Image and return the ID or -1 on error*/
+ image.bitmap = ReadImage (fd,
+ Bitmap_Head.biWidth,
+ Bitmap_Head.biHeight,
+ ColorMap,
+ Bitmap_Head.biBitCnt,
+ Bitmap_Head.biCompr,
+ rowbytes,
+ Grey);
+ BITMAP_WIDTH (image) = (at_dimen_t) Bitmap_Head.biWidth;
+ BITMAP_HEIGHT (image) = (at_dimen_t) Bitmap_Head.biHeight;
+ BITMAP_PLANES (image) = Grey ? 1 : 3;
+
+ return (image);
+}
+
+static int
+ReadColorMap (FILE *fd,
+ unsigned char buffer[256][3],
+ int number,
+ int size,
+ int *grey)
+{
+ int i;
+ unsigned char rgb[4];
+
+ *grey=(number>2);
+ for (i = 0; i < number ; i++)
+ {
+ if (!ReadOK (fd, rgb, size))
+ FATALP ("BMP: Bad colormap");
+
+ /* 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]));
+ }
+ return 0;
+}
+
+static unsigned char*
+ReadImage (FILE *fd,
+ int width,
+ int height,
+ unsigned char cmap[256][3],
+ int bpp,
+ int compression,
+ int rowbytes,
+ int grey)
+{
+ unsigned char v,howmuch;
+ int xpos = 0, ypos = 0;
+ unsigned char *image;
+ unsigned char *temp, *buffer;
+ long rowstride, channels;
+ unsigned short rgb;
+ int i, j;
+
+ if (bpp >= 16) /* color image */
+ {
+ XMALLOCT (image, unsigned char*, width * height * 3 * sizeof (unsigned char));
+ channels = 3;
+ }
+ else if (grey) /* grey image */
+ {
+ XMALLOCT (image, unsigned char*, width * height * 1 * sizeof (unsigned char));
+ channels = 1;
+ }
+ else /* indexed image */
+ {
+ XMALLOCT (image, unsigned char*, width * height * 1 * sizeof (unsigned char));
+ channels = 1;
+ }
+
+ XMALLOCT (buffer, unsigned char*, rowbytes);
+ rowstride = width * channels;
+
+ ypos = height - 1; /* Bitmaps begin in the lower left corner */
+
+ switch (bpp) {
+
+ case 32:
+ {
+ while (ReadOK (fd, buffer, rowbytes))
+ {
+ temp = image + (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 */
+ }
+ }
+ break;
+
+ case 24:
+ {
+ while (ReadOK (fd, buffer, rowbytes))
+ {
+ temp = image + (ypos * rowstride);
+ for (xpos= 0; xpos < width; ++xpos)
+ {
+ *(temp++)= buffer[xpos * 3 + 2];
+ *(temp++)= buffer[xpos * 3 + 1];
+ *(temp++)= buffer[xpos * 3];
+ }
+ --ypos; /* next line */
+ }
+ }
+ break;
+
+ case 16:
+ {
+ while (ReadOK (fd, buffer, rowbytes))
+ {
+ temp = image + (ypos * rowstride);
+ for (xpos= 0; xpos < width; ++xpos)
+ {
+ rgb= ToS(&buffer[xpos * 2]);
+ *(temp++)= (unsigned char)(((rgb >> 10) & 0x1f) * 8);
+ *(temp++)= (unsigned char)(((rgb >> 5) & 0x1f) * 8);
+ *(temp++)= (unsigned char)(((rgb) & 0x1f) * 8);
+ }
+ --ypos; /* next line */
+ }
+ }
+ break;
+
+ case 8:
+ case 4:
+ case 1:
+ {
+ if (compression == 0)
+ {
+ while (ReadOK (fd, &v, 1))
+ {
+ for (i = 1; (i <= (8 / bpp)) && (xpos < width); i++, xpos++)
+ {
+ temp = (unsigned char*) (image + (ypos * rowstride) + (xpos * channels));
+ *temp= (unsigned char)(( v & ( ((1<<bpp)-1) << (8-(i*bpp)) ) ) >> (8-(i*bpp)));
+ }
+ if (xpos == width)
+ {
+ (void) ReadOK (fd, buffer, rowbytes - 1 -
+ (width * bpp - 1) / 8);
+ ypos--;
+ xpos = 0;
+
+ }
+ if (ypos < 0)
+ break;
+ }
+ break;
+ }
+ else
+ {
+ while (ypos >= 0 && xpos <= width)
+ {
+ (void) ReadOK (fd, buffer, 2);
+ if ((unsigned char) buffer[0] != 0)
+ /* Count + Color - record */
+ {
+ for (j = 0; ((unsigned char) j < (unsigned char) buffer[0]) && (xpos < width);)
+ {
+#ifdef DEBUG2
+ printf("%u %u | ",xpos,width);
+#endif
+ for (i = 1;
+ ((i <= (8 / bpp)) &&
+ (xpos < width) &&
+ ((unsigned char) j < (unsigned char) buffer[0]));
+ i++, xpos++, j++)
+ {
+ temp = image + (ypos * rowstride) + (xpos * channels);
+ *temp = (unsigned char) ((buffer[1] & (((1<<bpp)-1) << (8 - (i * bpp)))) >> (8 - (i * bpp)));
+ }
+ }
+ }
+ if (((unsigned char) buffer[0] == 0) && ((unsigned char) buffer[1] > 2))
+ /* uncompressed record */
+ {
+ howmuch = buffer[1];
+ for (j = 0; j < howmuch; j += (8 / bpp))
+ {
+ (void) ReadOK (fd, &v, 1);
+ i = 1;
+ while ((i <= (8 / bpp)) && (xpos < width))
+ {
+ temp = image + (ypos * rowstride) + (xpos * channels);
+ *temp = (unsigned char) ((v & (((1<<bpp)-1) << (8-(i*bpp)))) >> (8-(i*bpp)));
+ i++;
+ xpos++;
+ }
+ }
+
+ if ((howmuch % 2) && (bpp==4))
+ howmuch++;
+
+ if ((howmuch / (8 / bpp)) % 2)
+ (void) ReadOK (fd, &v, 1);
+ /*if odd(x div (8 div bpp )) then blockread(f,z^,1);*/
+ }
+ if (((unsigned char) buffer[0] == 0) && ((unsigned char) buffer[1]==0))
+ /* Line end */
+ {
+ ypos--;
+ xpos = 0;
+ }
+ if (((unsigned char) buffer[0]==0) && ((unsigned char) buffer[1]==1))
+ /* Bitmap end */
+ {
+ break;
+ }
+ if (((unsigned char) buffer[0]==0) && ((unsigned char) buffer[1]==2))
+ /* Deltarecord */
+ {
+ (void) ReadOK (fd, buffer, 2);
+ xpos += (unsigned char) buffer[0];
+ ypos -= (unsigned char) buffer[1];
+ }
+ }
+ break;
+ }
+ }
+ break;
+ default:
+ /* This is very bad, we should not be here */
+ ;
+ }
+
+ /* fclose (fd); */
+ if (bpp <= 8)
+ {
+ unsigned char *temp2, *temp3;
+ unsigned char index;
+ temp2 = temp = image;
+ XMALLOCT (image, unsigned char*, width * height * 3 * sizeof (unsigned char));
+ temp3 = image;
+ for (ypos = 0; ypos < height; ypos++)
+ {
+ for (xpos = 0; xpos < width; xpos++)
+ {
+ index = *temp2++;
+ *temp3++ = cmap[index][0];
+ if (!grey)
+ {
+ *temp3++ = cmap[index][1];
+ *temp3++ = cmap[index][2];
+ }
+ }
+ }
+ XFREE (temp);
+ }
+
+ XFREE (buffer);
+ return image;
+}
+
+#if 0 /**** pts ****/
+FILE *errorfile;
+char *prog_name = "bmp";
+char *filename;
+int interactive_bmp;
+#endif
+
+static long
+ToL (unsigned char *puffer)
+{
+ return (puffer[0] | puffer[1]<<8 | puffer[2]<<16 | puffer[3]<<24);
+}
+
+static short
+ToS (unsigned char *puffer)
+{
+ return ((short)(puffer[0] | puffer[1]<<8));
+}