]> granicus.if.org Git - nethack/commitdiff
*** empty log message ***
authorjwalz <jwalz>
Sat, 5 Jan 2002 21:06:00 +0000 (21:06 +0000)
committerjwalz <jwalz>
Sat, 5 Jan 2002 21:06:00 +0000 (21:06 +0000)
win/gem/bitmfile.c [new file with mode: 0644]

diff --git a/win/gem/bitmfile.c b/win/gem/bitmfile.c
new file mode 100644 (file)
index 0000000..13e0073
--- /dev/null
@@ -0,0 +1,340 @@
+/****************************\
+* Bitmap mit Farbtabelle als *
+* Graphik-Datei speichern               *
+* Autor: Gabriel Schmidt                *
+* (c) 1992 by MAXON-Computer *
+* Modifiziert von Sebastian     *
+* Bieber, Dez. 1994                                     *
+* -> Programmcode                                               *
+\****************************/
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "bitmfile.h"
+
+/* --- (X) IMG-Implementation ----------------- */
+
+#define IMG_COMPRESSED
+
+typedef struct
+       {
+       UWORD img_version;
+       UWORD img_headlen;
+       UWORD img_nplanes;
+       UWORD img_patlen;
+       UWORD img_pixw;
+       UWORD img_pixh;
+       UWORD img_w;
+       UWORD img_h;
+       } IMG_HEADER;
+
+typedef enum {NONE, SOLID0, SOLID1, PATRUN, BITSTR} IMG_MODE;
+
+typedef UBYTE IMG_SOLID;
+
+typedef enum { RGB=0, CMY=1, Pantone=2 } XIMG_COLMODEL;
+
+typedef struct
+       {
+       ULONG img_ximg;
+       XIMG_COLMODEL img_colmodel;
+       } XIMG_HEADER;
+
+typedef struct RGB XIMG_RGB;
+
+
+int bitmap_to_img(FILE_TYP typ,        int ww, int wh,
+                                                                       unsigned int pixw, unsigned int pixh,
+                                                                       unsigned int planes, unsigned int colors,
+                                                                       const char *filename,
+                                                                       void(*get_color)(unsigned int colind, struct RGB *rgb),
+                                                                       void(*get_pixel)(int x, int y, unsigned int *colind) )
+       {
+       int file, error, cnt;
+       IMG_HEADER header;
+       XIMG_HEADER xheader;
+       XIMG_RGB xrgb;
+       IMG_MODE mode;
+       UBYTE *line_buf, *write_buf;
+       register UBYTE *startpnt, *bufpnt;
+       unsigned int colind, line_len, line, bit;
+       register unsigned int byte;
+       register UBYTE count;
+
+       /* fill in (X) IMG-Header */
+
+       header.img_version = 1;
+       header.img_headlen = (UWORD) sizeof(header) /2;
+       if (typ == XIMG)
+               header.img_headlen += (UWORD)(sizeof(xheader)+colors*sizeof(xrgb))/2;
+
+       header.img_nplanes      = planes;
+       header.img_patlen               = 2;
+       header.img_pixw                 = pixw;
+       header.img_pixh                 = pixh;
+       header.img_w                            = ww;
+       header.img_h                            = wh;
+
+       xheader.img_ximg                = XIMG_MAGIC;
+       xheader.img_colmodel= RGB;
+
+       /* calculate linelength, allocate buffer. */
+
+       line_len        = (ww+7)/8;
+
+       line_buf        = malloc((size_t)planes*line_len);
+       if (line_buf == NULL)
+               return(ENOMEM);
+
+       /* Worst case: the bufferd line could grow to max. 3 times the length */
+       /* of the original!                                                                                                                                     */
+
+       write_buf = malloc((size_t)3*line_len);
+       if (write_buf == NULL)
+               {
+               free(line_buf);
+               return(ENOMEM);
+               };
+
+       /* open file */
+
+       file = open(filename, O_WRONLY | O_CREAT | O_TRUNC);
+       if (file<0)
+               {
+               error = errno;
+               free(line_buf);
+               free(write_buf);
+               return(error);
+               };
+
+       /* write Header */
+
+       if (write (file, &header, sizeof(header)) != sizeof(header) ||
+                 (typ == XIMG &&       write (file, &xheader, sizeof(xheader) ) != sizeof(xheader)))
+                       {
+                       error = errno;
+                       close(file);
+                       free(line_buf);
+                       free(write_buf);
+                       return(error);
+                       };
+
+       /* save the colortable if possible */
+
+       if ( typ == XIMG )
+       for (cnt=0; cnt<colors; cnt++)
+               {
+               get_color(cnt,&xrgb);
+               if (write(file,&xrgb,sizeof(xrgb)) != sizeof(xrgb))
+                       {
+                       error = errno;
+                       close(file);
+                       free(line_buf);
+                       free(write_buf);
+                       return(error);
+                       };
+               };
+
+       /* And now line by line ... */
+
+       for (line=0; line<wh; line++)
+               {
+               /* get pixel, split it up and */
+               /* store it as planes in buffer */
+
+               for (byte=0; byte<line_len; byte++)
+                       {
+                       for (cnt=0; cnt<planes; cnt++)
+                               line_buf[cnt*line_len+byte] = 0x00;
+
+                       for (bit=0; bit<8; bit++)
+                               {
+                               if (8*byte+bit < ww)
+                                       get_pixel(8*byte+bit, line, &colind);
+
+                               for (cnt=0; cnt<planes; cnt++)
+                                       {
+                                       line_buf[cnt*line_len+byte] <<= 1;
+                                       line_buf[cnt*line_len+byte]  |= colind & 0x01;
+                                       colind >>= 1;
+                                       };
+                               };
+                       };
+
+               /* compress bitstrings in buffer */
+               /* and write it to file        */
+
+               for (cnt=0; cnt<planes; cnt++)
+                       {
+                       /* Bitstringpointer to start of plane */
+
+                       startpnt = &line_buf[cnt*line_len];
+                       bufpnt = write_buf;
+
+                       while (startpnt < &line_buf[(cnt+1)*line_len])
+                               {
+                               /*********************************************/
+                               /* Which _new_ compression-mode "fits" the      */
+                               /* the current byte?                                                                    */
+                               /* Note: the compressing modes get choosen      */
+                               /* "positive". The non compressing BITSTR-      */
+                               /* mode is choosen only if nothing else                 */
+                               /* "fits" ...                                                                                   */
+                               /*********************************************/
+
+                               switch (*startpnt)
+                                       {
+                                       case 0x00:
+                                               mode = SOLID0;
+                                               break;
+                                       case 0xFF:
+                                               mode = SOLID1;
+                                               break;
+                                       default:
+                                               if ( startpnt   <  &line_buf[(cnt+1)*line_len-3] &&
+                                                               *(startpnt)   == *(startpnt+2)                                           &&
+                                                               *(startpnt+1) == *(startpnt+3)                                           )
+                                                       mode = PATRUN;
+                                               else
+                                                       mode = BITSTR;
+                                       };
+
+                               /************************************************/
+                               /* The mode is choosen, now work with it.                       */
+                               /* The compressing modi stay current as long as */
+                               /* possible.                                                                                            */
+                               /************************************************/
+
+                               count = 0;
+
+                               switch (mode)
+                                       {
+                                       case SOLID0:
+                                               while ( (startpnt < &line_buf[(cnt+1)*line_len])        &&
+                                                                               (*(startpnt)==0x00)                                                                                     &&
+                                                                               (count < 0x7F)                                                                                                          )
+                                                                       {
+                                                                       startpnt++;
+                                                                       count++;
+                                                                       };
+                                               *(bufpnt++) = count;
+                                               break;
+
+                                       case SOLID1:
+                                               while ( (startpnt < &line_buf[(cnt+1)*line_len])        &&
+                                                                               (*(startpnt)==0xFF)                                                                                     &&
+                                                                               (count < 0x7F)                                                                                                          )
+                                                                       {
+                                                                       startpnt++;
+                                                                       count++;
+                                                                       };
+                                               *(bufpnt++) = 0x80 | count;
+                                               break;
+
+                                       case PATRUN:
+                                               *(bufpnt++) = 0x00;
+                                               startpnt += 2;
+                                               count = 1;
+                                               while ( startpnt < &line_buf[(cnt+1)*line_len-1]        &&
+                                                                               *(startpnt)             == *(startpnt-2)                                                &&
+                                                                               *(startpnt+1)   == *(startpnt-1)                                                &&
+                                                                               (count < 0xFF)                                                                                                          )
+                                                                       {
+                                                                       count++;
+                                                                       startpnt += 2;
+                                                                       };
+                                               *(bufpnt++) = count;
+                                               *(bufpnt++) = *(startpnt-2);
+                                               *(bufpnt++) = *(startpnt-1);
+                                               break;
+
+                                       /************************************************/
+                                       /* The while Condition is ment as follows:              */
+                                       /*                                                                                                                                                                                      */
+                                       /* while ( NOT(2-Byte-Solidrun possible)        &&              */
+                                       /*                       NOT(6-Byte-Patternrun possible)        &&              */
+                                       /*                               count < 0xFF                                                                           &&              */
+                                       /*                       still Bytes remaining                  )                       */
+                                       /*                                                                                                                                                                                      */
+                                       /* As soon as a _compressing_ alternative       shows   */
+                                       /* up, BITSTR gets cancelled!                                                   */
+                                       /************************************************/
+
+                                       case BITSTR:
+                                               *(bufpnt++) = 0x80;
+                                               while ( !(((startpnt+count)<&line_buf[(cnt+1)*line_len-1])&&
+                                                                                       (((*(startpnt+count)==0xFF) && (*(startpnt+count+1)==0xFF))||
+                                                                                        ((*(startpnt+count)==0x00) && (*(startpnt+count+1)==0x00))))           &&
+                                                                               !(((startpnt+count)<&line_buf[(cnt+1)*line_len-5])&&
+                                                                                       (*(startpnt+count)   == *(startpnt+count+2))&&
+                                                                                       (*(startpnt+count+1) == *(startpnt+count+3))&&
+                                                                                       (*(startpnt+count)   == *(startpnt+count+4))&&
+                                                                                       (*(startpnt+count+1) == *(startpnt+count+5)))                                                                                           &&
+                                                                               (count < 0xFF)                                                                                                                                                                                                                          &&
+                                                                               ((startpnt+count) < &line_buf[(cnt+1)*line_len])                                                                                        )
+                                                                               count++;
+                                               *(bufpnt++) = count;
+                                               for(; count>0; count--)
+                                                       *(bufpnt++) = *(startpnt++);
+                                               break;
+                                       };
+                               };
+
+                       if (write(file,write_buf,bufpnt-write_buf) != (bufpnt-write_buf))
+                               {
+                               error = errno;
+                               close(file);
+                               free(line_buf);
+                               free(write_buf);
+                               return(error);
+                               };
+
+                       };
+               };
+
+       /*close file, free buffer. */
+
+       close(file);
+       free(line_buf);
+       free(write_buf);
+       return(0);
+
+}
+
+/*---filetype-dispatcher--------------------*/
+
+const char *get_file_ext(FILE_TYP typ)
+       {
+       switch (typ)
+               {
+               case IMG:
+               case XIMG:
+                       return("IMG");
+               default:
+                       return("");
+               };
+}
+
+
+int bitmap_to_file(FILE_TYP typ, int ww, int wh,
+                                                                        unsigned int pwx, unsigned int pwy,
+                                                                        unsigned int planes, unsigned int colors,
+                                                                        const char *filename,
+                                                                        void (*get_color)(unsigned int colind, struct RGB *rgb),
+                                                                        void (*get_pixel)(int x, int y, unsigned int *colind))
+       {
+
+       switch (typ)
+               {
+               case IMG:
+               case XIMG:
+                       return(bitmap_to_img(typ,ww,wh,pwx,pwy,planes,colors,filename,get_color,get_pixel));
+               default:
+                       return(-1);
+               };
+}
+