--- xvbmp.c
+++ xvbmp.c	Wed Jul 28 15:16:05 2004
@@ -32,7 +32,7 @@
 static int   loadBMP1   PARM((FILE *, byte *, u_int, u_int));
 static int   loadBMP4   PARM((FILE *, byte *, u_int, u_int, u_int));
 static int   loadBMP8   PARM((FILE *, byte *, u_int, u_int, u_int));
-static int   loadBMP24  PARM((FILE *, byte *, u_int, u_int));
+static int   loadBMP24  PARM((FILE *, byte *, u_int, u_int, u_int));
 static u_int getshort   PARM((FILE *));
 static u_int getint     PARM((FILE *));
 static void  putshort   PARM((FILE *, int));
@@ -127,7 +127,8 @@
 
 
   /* error checking */
-  if ((biBitCount!=1 && biBitCount!=4 && biBitCount!=8 && biBitCount!=24) || 
+  if ((biBitCount!=1 && biBitCount!=4 && biBitCount!=8 && 
+       biBitCount!=24 && biBitCount!=32) || 
       biPlanes!=1 || biCompression>BI_RLE4) {
 
     sprintf(buf,"Bogus BMP File!  (bitCount=%d, Planes=%d, Compression=%d)",
@@ -137,7 +138,8 @@
     goto ERROR;
   }
 
-  if (((biBitCount==1 || biBitCount==24) && biCompression != BI_RGB) ||
+  if (((biBitCount==1 || biBitCount==24 || biBitCount==32)
+       && biCompression != BI_RGB) ||
       (biBitCount==4 && biCompression==BI_RLE8) ||
       (biBitCount==8 && biCompression==BI_RLE4)) {
 
@@ -159,7 +161,7 @@
   }
 
   /* load up colormap, if any */
-  if (biBitCount!=24) {
+  if (biBitCount!=24 && biBitCount!=32) {
     int i, cmaplen;
 
     cmaplen = (biClrUsed) ? biClrUsed : 1 << biBitCount;
@@ -197,7 +199,7 @@
 
   /* create pic8 or pic24 */
 
-  if (biBitCount==24) {
+  if (biBitCount==24 || biBitCount==32) {
     pic24 = (byte *) calloc((size_t) biWidth * biHeight * 3, (size_t) 1);
     if (!pic24) return (bmpError(bname, "couldn't malloc 'pic24'"));
   }
@@ -212,16 +214,18 @@
   if      (biBitCount == 1) rv = loadBMP1(fp,pic8,biWidth,biHeight);
   else if (biBitCount == 4) rv = loadBMP4(fp,pic8,biWidth,biHeight,
 					  biCompression);
-  else if (biBitCount == 8) rv = loadBMP8(fp,pic8,biWidth,biHeight,
+  else if (biBitCount == 8) rv = loadBMP8(fp,pic8,biWidth,biHeight, 
 					  biCompression);
-  else                      rv = loadBMP24(fp,pic24,biWidth,biHeight);
+  else                      rv = loadBMP24(fp,pic24,biWidth,biHeight,
+					   biBitCount);
+
 
   if (rv) bmpError(bname, "File appears truncated.  Winging it.\n");
 
   fclose(fp);
 
 
-  if (biBitCount == 24) {
+  if (biBitCount == 24 || biBitCount == 32) {
     pinfo->pic  = pic24;
     pinfo->type = PIC24;
   }
@@ -264,12 +268,13 @@
      u_int  w,h;
 {
   int   i,j,c,bitnum,padw;
-  byte *pp;
+  byte *pp = pic8 + ((h - 1) * w);
+  size_t l = w*h;
 
   c = 0;
   padw = ((w + 31)/32) * 32;  /* 'w', padded to be a multiple of 32 */
 
-  for (i=h-1; i>=0; i--) {
+  for (i=h-1; i>=0 && (pp - pic8 <= l); i--) {
     pp = pic8 + (i * w);
     if ((i&0x3f)==0) WaitCursor();
     for (j=bitnum=0; j<padw; j++,bitnum++) {
@@ -298,8 +303,8 @@
      u_int  w,h,comp;
 {
   int   i,j,c,c1,x,y,nybnum,padw,rv;
-  byte *pp;
-  
+  byte *pp = pic8 + ((h - 1) * w);
+  size_t l = w*h;
   
   rv = 0;
   c = c1 = 0;
@@ -307,7 +312,7 @@
   if (comp == BI_RGB) {   /* read uncompressed data */
     padw = ((w + 7)/8) * 8; /* 'w' padded to a multiple of 8pix (32 bits) */
     
-    for (i=h-1; i>=0; i--) {
+    for (i=h-1; i>=0 && (pp - pic8 <= l); i--) {
       pp = pic8 + (i * w);
       if ((i&0x3f)==0) WaitCursor();
       
@@ -335,7 +340,7 @@
       
       if (c) {                                   /* encoded mode */
 	c1 = getc(fp);
-	for (i=0; i<c; i++,x++,pp++) 
+	for (i=0; i<c && (pp - pic8 <= l); i++,x++,pp++) 
 	  *pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
       }
       
@@ -355,7 +360,7 @@
 	}
 	
 	else {                                   /* absolute mode */
-	  for (i=0; i<c; i++, x++, pp++) {
+	  for (i=0; i<c && (pp - pic8 <= l); i++, x++, pp++) {
 	    if ((i&1) == 0) c1 = getc(fp);
 	    *pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
 	  }
@@ -384,14 +389,15 @@
      u_int  w,h,comp;
 {
   int   i,j,c,c1,padw,x,y,rv;
-  byte *pp;
+  byte *pp = pic8 + ((h - 1) * w);
+  size_t l = w*h;
   
   rv = 0;
 
   if (comp == BI_RGB) {   /* read uncompressed data */
     padw = ((w + 3)/4) * 4; /* 'w' padded to a multiple of 4pix (32 bits) */
 
-    for (i=h-1; i>=0; i--) {
+    for (i=h-1; i>=0 && (pp - pic8 <= l); i--) {
       pp = pic8 + (i * w);
       if ((i&0x3f)==0) WaitCursor();
 
@@ -412,7 +418,7 @@
 
       if (c) {                                   /* encoded mode */
 	c1 = getc(fp);
-	for (i=0; i<c; i++,x++,pp++) *pp = c1;
+	for (i=0; i<c && (pp - pic8 <= l); i++,x++,pp++) *pp = c1;
       }
 
       else {    /* c==0x00  :  escape codes */
@@ -431,7 +437,7 @@
 	}
 
 	else {                                   /* absolute mode */
-	  for (i=0; i<c; i++, x++, pp++) {
+	  for (i=0; i<c && (pp - pic8 <= l); i++, x++, pp++) {
 	    c1 = getc(fp);
 	    *pp = c1;
 	  }
@@ -454,19 +460,21 @@
 
 
 /*******************************************/
-static int loadBMP24(fp, pic24, w, h)
+static int loadBMP24(fp, pic24, w, h, bits)
      FILE *fp;
      byte *pic24;
-     u_int  w,h;
+     u_int  w,h, bits;
 {
   int   i,j,padb,rv;
-  byte *pp;
+  byte *pp = pic24 + ((h - 1) * w * 3);
+  size_t l = w*h*3;
 
   rv = 0;
 
   padb = (4 - ((w*3) % 4)) & 0x03;  /* # of pad bytes to read at EOscanline */
+  if (bits==32) padb = 0;
 
-  for (i=h-1; i>=0; i--) {
+  for (i=h-1; i>=0 && (pp - pic24 <= l); i--) {
     pp = pic24 + (i * w * 3);
     if ((i&0x3f)==0) WaitCursor();
     
@@ -474,6 +482,7 @@
       pp[2] = getc(fp);   /* blue */
       pp[1] = getc(fp);   /* green */
       pp[0] = getc(fp);   /* red */
+      if (bits==32) getc(fp);
       pp += 3;
     }
 
