[AD] loading pcx from memory

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


Hello !

I'm currently work in on a game around allegro and I needed a way of
loading pcx images directly from the memory rathen than a file as in
load_pcx(). Actually I needed it so bad that I implemented that future
using allegro's pcx.c. I feel that it is a very valuble future so I think
it should be included in allegro in someway. Anyway here my patch to
allegro 3.12 wich adds load_mem_pcx() function, where 'mem' stands for
memory. Your are wellcome to tweak it as mush as you find nessesary.

Well, that's all,
happy hacking :)
/Elmir J

---- the patch -----
diff -ur allegro/allegro.h sqeeal/allegro.h
--- allegro/allegro.h	Fri Aug 27 13:00:52 1999
+++ sqeeal/allegro.h	Thu Jul  5 05:49:18 2001
@@ -2353,6 +2353,7 @@
 BITMAP *load_bmp(char *filename, RGB *pal);
 BITMAP *load_lbm(char *filename, RGB *pal);
 BITMAP *load_pcx(char *filename, RGB *pal);
+BITMAP *load_mem_pcx(char *buf, int buf_size, RGB *pal);
 BITMAP *load_tga(char *filename, RGB *pal);
 
 int save_bitmap(char *filename, BITMAP *bmp, RGB *pal);
diff -ur allegro/src/pcx.c sqeeal/src/pcx.c
--- allegro/src/pcx.c	Sat Feb 20 16:46:10 1999
+++ sqeeal/src/pcx.c	Mon Jul  9 15:54:28 2001
@@ -33,8 +33,33 @@
 BITMAP *load_pcx(char *filename, RGB *pal)
 {
    PACKFILE *f;
+   int fsize,i;
+   char *buf;
    BITMAP *b;
-   int c;
+
+   f = pack_fopen(filename, F_READ);
+   if (!f)
+      return NULL;
+
+   fsize = (int)file_size(filename);
+   buf = malloc(fsize);
+
+   if (pack_fread(buf,(long)fsize,f)!=fsize){
+       free(buf);
+       return NULL;
+   }
+
+   b = load_mem_pcx(buf,fsize,pal);
+
+   pack_fclose(f);
+   free(buf);
+   return b;
+}
+
+BITMAP *load_mem_pcx(char *buf, int buf_size, RGB *pal)
+{
+   BITMAP *b;
+   int c, p, tmp;
    int width, height;
    int bpp, bytes_per_line;
    int xx, po;
@@ -42,54 +67,63 @@
    char ch;
    int dest_depth;
 
-   f = pack_fopen(filename, F_READ);
-   if (!f)
-      return NULL;
-
-   pack_getc(f);                    /* skip manufacturer ID */
-   pack_getc(f);                    /* skip version flag */
-   pack_getc(f);                    /* skip encoding flag */
+                             /* skip manufacturer ID,
+                                skip version flag and
+                                skip encoding flag    */
 
-   if (pack_getc(f) != 8) {         /* we like 8 bit color planes */
-      pack_fclose(f);
+   if (buf[3] != 8) {         /* we like 8 bit color planes */
       return NULL;
    }
 
-   width = -(pack_igetw(f));        /* xmin */
-   height = -(pack_igetw(f));       /* ymin */
-   width += pack_igetw(f) + 1;      /* xmax */
-   height += pack_igetw(f) + 1;     /* ymax */
 
-   pack_igetl(f);                   /* skip DPI values */
-
-   for (c=0; c<16; c++) {           /* read the 16 color pallete */
-      pal[c].r = pack_getc(f) / 4;
-      pal[c].g = pack_getc(f) / 4;
-      pal[c].b = pack_getc(f) / 4;
+   tmp = 0;
+   memcpy(&tmp,buf + 4,2);           /* xmin */
+   width = - tmp;
+   memcpy(&tmp,buf + 6,2);
+   height = -(tmp);                  /* ymin */
+   memcpy(&tmp,buf + 8,2);
+   width += tmp + 1;                 /* xmax */
+   memcpy(&tmp,buf + 10,2);
+   height += tmp + 1;                /* ymax */
+
+   /* p += 4 */                      /* skip DPI values */
+   p = 16;
+   tmp = 0;
+   for (c=0; c<16; c++) {            /* read the 16 color pallete */
+      memcpy(&tmp,buf + p,1);
+      pal[c].r = tmp / 4;
+      memcpy(&tmp,buf + p + 1 ,1);
+      pal[c].g = tmp / 4;
+      memcpy(&tmp,buf + p + 2 ,1);
+      pal[c].b = tmp / 4;
+      p += 3;
    }
+   p ++;
 
-   pack_getc(f);
+   memcpy(&tmp,buf + p ,1);           /* how many color planes? */
+   p++;
 
-   bpp = pack_getc(f) * 8;          /* how many color planes? */
+   bpp = tmp * 8;          
  #ifdef ALLEGRO_COLOR24
    if ((bpp != 8) && (bpp != 24)) {
  #else
    if (bpp != 8) {
  #endif
-      pack_fclose(f);
       return NULL;
    }
 
    dest_depth = _color_load_depth(bpp);
-   bytes_per_line = pack_igetw(f);
 
-   for (c=0; c<60; c++)             /* skip some more junk */
-      pack_getc(f);
+   tmp = 0;
+   memcpy(&tmp,buf + p ,2);
+   bytes_per_line = tmp;
+
+
+   p += 62;             /* skip some more junk */
 
    b = create_bitmap_ex(bpp, width, height);
    if (!b) {
-      pack_fclose(f);
-      return FALSE;
+      return NULL;
    }
 
    for (y=0; y<height; y++) {       /* read RLE encoded PCX data */
@@ -97,10 +131,12 @@
       po = _rgb_r_shift_24/8;
 
       while (x < bytes_per_line*bpp/8) {
-	 ch = pack_getc(f);
+       memcpy(&ch,buf + p, 1);
+       p++;
 	 if ((ch & 0xC0) == 0xC0) {
 	    c = (ch & 0x3F);
-	    ch = pack_getc(f);
+          memcpy(&ch,buf + p, 1);
+          p++;
 	 }
 	 else
 	    c = 1;
@@ -133,12 +169,19 @@
    }
 
    if (bpp == 8) {                  /* look for a 256 color pallete */
-      while (!pack_feof(f)) { 
-	 if (pack_getc(f)==12) {
+      tmp = 0;
+      while (p<buf_size) {
+       memcpy(&tmp,buf + p, 1);
+       p++;
+	 if (tmp==12) {
 	    for (c=0; c<256; c++) {
-	       pal[c].r = pack_getc(f) / 4;
-	       pal[c].g = pack_getc(f) / 4;
-	       pal[c].b = pack_getc(f) / 4;
+             memcpy(&tmp,buf + p, 1);
+	       pal[c].r = tmp / 4;
+             memcpy(&tmp,buf + p + 1, 1);
+	       pal[c].g = tmp / 4;
+             memcpy(&tmp,buf + p + 2, 1);
+	       pal[c].b = tmp / 4;
+             p += 3;
 	    }
 	    break;
 	 }
@@ -147,20 +190,20 @@
    else
       generate_332_palette(pal);
 
-   pack_fclose(f);
-
-   if (errno) {
-      destroy_bitmap(b);
-      return FALSE;
-   }
+   /* why should we check for errno !!? */
+   /*
+   * if (errno) {
+   *   destroy_bitmap(b);
+   *   return NULL;
+   *}
+   */
 
    if (dest_depth != bpp)
       b = _fixup_loaded_bitmap(b, pal, dest_depth);
 
    return b;
-}
-
 
+}
 
 /* save_pcx:
  *  Writes a bitmap into a PCX file, using the specified pallete (this



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/