]> granicus.if.org Git - libjpeg-turbo/commitdiff
Completely refactor BMP library so that it takes advantage of the existing BMP and...
authorDRC <dcommander@users.sourceforge.net>
Tue, 24 May 2011 09:13:17 +0000 (09:13 +0000)
committerDRC <dcommander@users.sourceforge.net>
Tue, 24 May 2011 09:13:17 +0000 (09:13 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@622 632fc199-4ca6-4c93-a231-07263d6284db

bmp.c
bmp.h

diff --git a/bmp.c b/bmp.c
index 3ccc8772bb352c9e0a761c26effe010bc86ef54e..01353c72ff670901194e89ef59b6af80baa76260 100644 (file)
--- a/bmp.c
+++ b/bmp.c
-/* Copyright (C)2004 Landmark Graphics Corporation
- * Copyright (C)2005 Sun Microsystems, Inc.
+/*
+ * Copyright (C)2011 D. R. Commander.  All Rights Reserved.
  *
- * This library is free software and may be redistributed and/or modified under
- * the terms of the wxWindows Library License, Version 3.1 or (at your option)
- * any later version.  The full license is in the LICENSE.txt file included
- * with this distribution.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
  *
- * This library 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
- * wxWindows Library License for more details.
-*/
-
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <stdlib.h>
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of the libjpeg-turbo Project nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
 #include <stdio.h>
 #include <string.h>
-#ifdef _WIN32
- #include <io.h>
-#else
- #include <unistd.h>
-#endif
-#include "./rrutil.h"
-#include "./bmp.h"
-
-#ifndef BI_BITFIELDS
-#define BI_BITFIELDS 3L
-#endif
-#ifndef BI_RGB
-#define BI_RGB 0L
-#endif
-
-#define BMPHDRSIZE 54
-typedef struct _bmphdr
-{
-       unsigned short bfType;
-       unsigned int bfSize;
-       unsigned short bfReserved1, bfReserved2;
-       unsigned int bfOffBits;
-
-       unsigned int biSize;
-       int biWidth, biHeight;
-       unsigned short biPlanes, biBitCount;
-       unsigned int biCompression, biSizeImage;
-       int biXPelsPerMeter, biYPelsPerMeter;
-       unsigned int biClrUsed, biClrImportant;
-} bmphdr;
-
-static const char *__bmperr="No error";
-
-static const int ps[BMPPIXELFORMATS]={3, 4, 3, 4, 4, 4};
-static const int roffset[BMPPIXELFORMATS]={0, 0, 2, 2, 3, 1};
-static const int goffset[BMPPIXELFORMATS]={1, 1, 1, 1, 2, 2};
-static const int boffset[BMPPIXELFORMATS]={2, 2, 0, 0, 1, 3};
-
-#define _throw(m) {__bmperr=m;  retcode=-1;  goto finally;}
-#define _unix(f) {if((f)==-1) _throw(strerror(errno));}
-#define _catch(f) {if((f)==-1) {retcode=-1;  goto finally;}}
-
-#define readme(fd, addr, size) \
-       if((bytesread=read(fd, addr, (size)))==-1) _throw(strerror(errno)); \
-       if(bytesread!=(size)) _throw("Read error");
-
-void pixelconvert(unsigned char *srcbuf, enum BMPPIXELFORMAT srcformat,
-       int srcpitch, unsigned char *dstbuf, enum BMPPIXELFORMAT dstformat, int dstpitch,
-       int w, int h, int flip)
+#include <setjmp.h>
+#include <errno.h>
+#include <jpeglib.h>
+#include <jpegint.h>
+#include "cdjpeg.h"
+#include "bmp.h"
+
+
+/* This duplicates the functionality of the VirtualGL bitmap library using
+   the components from cjpeg and djpeg */
+
+
+/* Error handling (based on example in example.c) */
+
+static char errStr[JMSG_LENGTH_MAX]="No error";
+
+struct my_error_mgr
 {
-       unsigned char *srcptr, *srcptr0, *dstptr, *dstptr0;
-       int i, j;
+       struct jpeg_error_mgr pub;
+       jmp_buf setjmp_buffer;
+};
+typedef struct my_error_mgr *my_error_ptr;
 
-       srcptr=flip? &srcbuf[srcpitch*(h-1)]:srcbuf;
-       for(j=0, dstptr=dstbuf; j<h; j++,
-               srcptr+=flip? -srcpitch:srcpitch, dstptr+=dstpitch)
-       {
-               for(i=0, srcptr0=srcptr, dstptr0=dstptr; i<w; i++,
-                       srcptr0+=ps[srcformat], dstptr0+=ps[dstformat])
-               {
-                       dstptr0[roffset[dstformat]]=srcptr0[roffset[srcformat]];
-                       dstptr0[goffset[dstformat]]=srcptr0[goffset[srcformat]];
-                       dstptr0[boffset[dstformat]]=srcptr0[boffset[srcformat]];
-               }
-       }
+static void my_error_exit(j_common_ptr cinfo)
+{
+       my_error_ptr myerr=(my_error_ptr)cinfo->err;
+       (*cinfo->err->output_message)(cinfo);
+       longjmp(myerr->setjmp_buffer, 1);
 }
 
-int loadppm(int *fd, unsigned char **buf, int *w, int *h,
-       enum BMPPIXELFORMAT f, int align, int dstbottomup, int ascii)
+/* Based on output_message() in jerror.c */
+
+static void my_output_message(j_common_ptr cinfo)
 {
-       FILE *fs=NULL;  int retcode=0, scalefactor, dstpitch;
-       unsigned char *tempbuf=NULL;  char temps[255], temps2[255];
-       int numread=0, totalread=0, pixel[3], i, j;
+       (*cinfo->err->format_message)(cinfo, errStr);
+}
 
-       if((fs=fdopen(*fd, "r"))==NULL) _throw(strerror(errno));
+#define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m);  \
+       retval=-1;  goto bailout;}
+#define _throwunix(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s\n%s", m,  \
+       strerror(errno));  retval=-1;  goto bailout;}
 
-       do
-       {
-               if(!fgets(temps, 255, fs)) _throw("Read error");
-               if(strlen(temps)==0 || temps[0]=='\n') continue;
-               if(sscanf(temps, "%s", temps2)==1 && temps2[1]=='#') continue;
-               switch(totalread)
-               {
-                       case 0:
-                               if((numread=sscanf(temps, "%d %d %d", w, h, &scalefactor))==EOF)
-                                       _throw("Read error");
-                               break;
-                       case 1:
-                               if((numread=sscanf(temps, "%d %d", h, &scalefactor))==EOF)
-                                       _throw("Read error");
-                               break;
-                       case 2:
-                               if((numread=sscanf(temps, "%d", &scalefactor))==EOF)
-                                       _throw("Read error");
-                               break;
-               }
-               totalread+=numread;
-       } while(totalread<3);
-       if((*w)<1 || (*h)<1 || scalefactor<1) _throw("Corrupt PPM header");
-
-       dstpitch=(((*w)*ps[f])+(align-1))&(~(align-1));
-       if((*buf=(unsigned char *)malloc(dstpitch*(*h)))==NULL)
-               _throw("Memory allocation error");
-       if(ascii)
+
+static void pixelconvert(unsigned char *srcbuf, int srcpf, int srcbottomup,
+       unsigned char *dstbuf, int dstpf, int dstbottomup, int w, int h)
+{
+       unsigned char *srcptr=srcbuf, *srcptr2;
+       int srcps=tjPixelSize[srcpf];
+       int srcstride=srcbottomup? -w*srcps:w*srcps;
+       unsigned char *dstptr=dstbuf, *dstptr2;
+       int dstps=tjPixelSize[dstpf];
+       int dststride=dstbottomup? -w*dstps:w*dstps;
+       int row, col;
+
+       if(srcbottomup) srcptr=&srcbuf[w*srcps*(h-1)];
+       if(dstbottomup) dstptr=&dstbuf[w*dstps*(h-1)];
+       for(row=0; row<h; row++, srcptr+=srcstride, dstptr+=dststride)
        {
-               for(j=0; j<*h; j++)
+               for(col=0, srcptr2=srcptr, dstptr2=dstptr; col<w; col++, srcptr2+=srcps,
+                       dstptr2+=dstps)
                {
-                       for(i=0; i<*w; i++)
-                       {
-                               if(fscanf(fs, "%d%d%d", &pixel[0], &pixel[1], &pixel[2])!=3)
-                                       _throw("Read error");
-                               (*buf)[j*dstpitch+i*ps[f]+roffset[f]]=(unsigned char)(pixel[0]*255/scalefactor);
-                               (*buf)[j*dstpitch+i*ps[f]+goffset[f]]=(unsigned char)(pixel[1]*255/scalefactor);
-                               (*buf)[j*dstpitch+i*ps[f]+boffset[f]]=(unsigned char)(pixel[2]*255/scalefactor);
-                       }
+                       dstptr2[tjRedOffset[dstpf]]=srcptr2[tjRedOffset[srcpf]];
+                       dstptr2[tjGreenOffset[dstpf]]=srcptr2[tjGreenOffset[srcpf]];
+                       dstptr2[tjBlueOffset[dstpf]]=srcptr2[tjBlueOffset[srcpf]];
                }
        }
-       else
-       {
-               if(scalefactor!=255)
-                       _throw("Binary PPMs must have 8-bit components");
-               if((tempbuf=(unsigned char *)malloc((*w)*(*h)*3))==NULL)
-                       _throw("Memory allocation error");
-               if(fread(tempbuf, (*w)*(*h)*3, 1, fs)!=1) _throw("Read error");
-               pixelconvert(tempbuf, BMP_RGB, (*w)*3, *buf, f, dstpitch, *w, *h, dstbottomup);
-       }
-
-       finally:
-       if(fs) {fclose(fs);  *fd=-1;}
-       if(tempbuf) free(tempbuf);
-       return retcode;
 }
 
 
 int loadbmp(char *filename, unsigned char **buf, int *w, int *h, 
-       enum BMPPIXELFORMAT f, int align, int dstbottomup)
+       int dstpf, int bottomup)
 {
-       int fd=-1, bytesread, srcpitch, srcbottomup=1, srcps, dstpitch,
-               retcode=0;
-       unsigned char *tempbuf=NULL;
-       bmphdr bh;  int flags=O_RDONLY;
-
-       dstbottomup=dstbottomup? 1:0;
-       #ifdef _WIN32
-       flags|=O_BINARY;
-       #endif
-       if(!filename || !buf || !w || !h || f<0 || f>BMPPIXELFORMATS-1 || align<1)
-               _throw("invalid argument to loadbmp()");
-       if((align&(align-1))!=0)
-               _throw("Alignment must be a power of 2");
-       _unix(fd=open(filename, flags));
-
-       readme(fd, &bh.bfType, sizeof(unsigned short));
-       if(!littleendian())     bh.bfType=byteswap16(bh.bfType);
-
-       if(bh.bfType==0x3650)
+       int retval=0, dstps, srcpf, tempc;
+       struct jpeg_compress_struct cinfo;
+       struct my_error_mgr jerr;
+       cjpeg_source_ptr src;
+       FILE *file=NULL;
+
+       if(!filename || !buf || !w || !h || dstpf<0 || dstpf>=TJ_NUMPF)
+               _throw("loadbmp(): Invalid argument");
+
+       if((file=fopen(filename, "rb"))==NULL)
+               _throwunix("loadbmp(): Cannot open input file");
+
+       cinfo.err=jpeg_std_error(&jerr.pub);
+       jerr.pub.error_exit=my_error_exit;
+       jerr.pub.output_message=my_output_message;
+
+       if(setjmp(jerr.setjmp_buffer))
        {
-               _catch(loadppm(&fd, buf, w, h, f, align, dstbottomup, 0));
-               goto finally;
+               /* If we get here, the JPEG code has signaled an error. */
+               retval=-1;  goto bailout;
        }
-       if(bh.bfType==0x3350)
+
+       jpeg_create_compress(&cinfo);
+       if((tempc=getc(file))<0 || ungetc(tempc, file)==EOF)
+               _throwunix("loadbmp(): Could not read input file")
+       else if(tempc==EOF) _throw("loadbmp(): Input file contains no data");
+
+       if(tempc=='B')
        {
-               _catch(loadppm(&fd, buf, w, h, f, align, dstbottomup, 1));
-               goto finally;
+               if((src=jinit_read_bmp(&cinfo))==NULL)
+                       _throw("loadbmp(): Could not initialize bitmap loader");
        }
-
-       readme(fd, &bh.bfSize, sizeof(unsigned int));
-       readme(fd, &bh.bfReserved1, sizeof(unsigned short));
-       readme(fd, &bh.bfReserved2, sizeof(unsigned short));
-       readme(fd, &bh.bfOffBits, sizeof(unsigned int));
-       readme(fd, &bh.biSize, sizeof(unsigned int));
-       readme(fd, &bh.biWidth, sizeof(int));
-       readme(fd, &bh.biHeight, sizeof(int));
-       readme(fd, &bh.biPlanes, sizeof(unsigned short));
-       readme(fd, &bh.biBitCount, sizeof(unsigned short));
-       readme(fd, &bh.biCompression, sizeof(unsigned int));
-       readme(fd, &bh.biSizeImage, sizeof(unsigned int));
-       readme(fd, &bh.biXPelsPerMeter, sizeof(int));
-       readme(fd, &bh.biYPelsPerMeter, sizeof(int));
-       readme(fd, &bh.biClrUsed, sizeof(unsigned int));
-       readme(fd, &bh.biClrImportant, sizeof(unsigned int));
-
-       if(!littleendian())
+       else if(tempc=='P')
        {
-               bh.bfSize=byteswap(bh.bfSize);
-               bh.bfOffBits=byteswap(bh.bfOffBits);
-               bh.biSize=byteswap(bh.biSize);
-               bh.biWidth=byteswap(bh.biWidth);
-               bh.biHeight=byteswap(bh.biHeight);
-               bh.biPlanes=byteswap16(bh.biPlanes);
-               bh.biBitCount=byteswap16(bh.biBitCount);
-               bh.biCompression=byteswap(bh.biCompression);
-               bh.biSizeImage=byteswap(bh.biSizeImage);
-               bh.biXPelsPerMeter=byteswap(bh.biXPelsPerMeter);
-               bh.biYPelsPerMeter=byteswap(bh.biYPelsPerMeter);
-               bh.biClrUsed=byteswap(bh.biClrUsed);
-               bh.biClrImportant=byteswap(bh.biClrImportant);
+               if((src=jinit_read_ppm(&cinfo))==NULL)
+                       _throw("loadbmp(): Could not initialize bitmap loader");
        }
+       else _throw("loadbmp(): Unsupported file type");
 
-       if(bh.bfType!=0x4d42 || bh.bfOffBits<BMPHDRSIZE
-       || bh.biWidth<1 || bh.biHeight==0)
-               _throw("Corrupt bitmap header");
-       if((bh.biBitCount!=24 && bh.biBitCount!=32) || bh.biCompression!=BI_RGB)
-               _throw("Only uncompessed RGB bitmaps are supported");
-
-       *w=bh.biWidth;  *h=bh.biHeight;  srcps=bh.biBitCount/8;
-       if(*h<0) {*h=-(*h);  srcbottomup=0;}
-       srcpitch=(((*w)*srcps)+3)&(~3);
-       dstpitch=(((*w)*ps[f])+(align-1))&(~(align-1));
-
-       if(srcpitch*(*h)+bh.bfOffBits!=bh.bfSize) _throw("Corrupt bitmap header");
-       if((tempbuf=(unsigned char *)malloc(srcpitch*(*h)))==NULL
-       || (*buf=(unsigned char *)malloc(dstpitch*(*h)))==NULL)
-               _throw("Memory allocation error");
-       if(lseek(fd, (long)bh.bfOffBits, SEEK_SET)!=(long)bh.bfOffBits)
-               _throw(strerror(errno));
-       _unix(bytesread=read(fd, tempbuf, srcpitch*(*h)));
-       if(bytesread!=srcpitch*(*h)) _throw("Read error");
-
-       pixelconvert(tempbuf, BMP_BGR, srcpitch, *buf, f, dstpitch, *w, *h, 
-               srcbottomup!=dstbottomup);
-
-       finally:
-       if(tempbuf) free(tempbuf);
-       if(fd!=-1) close(fd);
-       return retcode;
-}
-
-#define writeme(fd, addr, size) \
-       if((byteswritten=write(fd, addr, (size)))==-1) _throw(strerror(errno)); \
-       if(byteswritten!=(size)) _throw("Write error");
+       src->input_file=file;
+       (*src->start_input)(&cinfo, src);
+       (*cinfo.mem->realize_virt_arrays)((j_common_ptr)&cinfo);
 
-int saveppm(char *filename, unsigned char *buf, int w, int h,
-       enum BMPPIXELFORMAT f, int srcpitch, int srcbottomup)
-{
-       FILE *fs=NULL;  int retcode=0;
-       unsigned char *tempbuf=NULL;
+       *w=cinfo.image_width;  *h=cinfo.image_height;
 
-       if((fs=fopen(filename, "wb"))==NULL) _throw(strerror(errno));
-       if(fprintf(fs, "P6\n")<1) _throw("Write error");
-       if(fprintf(fs, "%d %d\n", w, h)<1) _throw("Write error");
-       if(fprintf(fs, "255\n")<1) _throw("Write error");
+       if(cinfo.input_components==1 && cinfo.in_color_space==JCS_RGB)
+               srcpf=TJPF_GRAY;
+       else srcpf=TJPF_RGB;
 
-       if((tempbuf=(unsigned char *)malloc(w*h*3))==NULL)
-               _throw("Memory allocation error");
+       dstps=tjPixelSize[dstpf];
+       if((*buf=(unsigned char *)malloc((*w)*(*h)*dstps))==NULL)
+               _throw("loadbmp(): Memory allocation failure");
 
-       pixelconvert(buf, f, srcpitch, tempbuf, BMP_RGB, w*3, w, h, 
-               srcbottomup);
+       while(cinfo.next_scanline<cinfo.image_height)
+       {
+               int i, nlines=(*src->get_pixel_rows)(&cinfo, src);
+               for(i=0; i<nlines; i++)
+               {
+                       unsigned char *outbuf;  int row;
+                       row=cinfo.next_scanline+i;
+                       if(bottomup) outbuf=&(*buf)[((*h)-row-1)*(*w)*dstps];
+                       else outbuf=&(*buf)[row*(*w)*dstps];
+                       pixelconvert(src->buffer[i], srcpf, 0, outbuf, dstpf, bottomup, *w,
+                               nlines);
+               }
+               cinfo.next_scanline+=nlines;
+  }
 
-       if((fwrite(tempbuf, w*h*3, 1, fs))!=1) _throw("Write error");
+       (*src->finish_input)(&cinfo, src);
 
-       finally:
-       if(tempbuf) free(tempbuf);
-       if(fs) fclose(fs);
-       return retcode;
+       bailout:
+       jpeg_destroy_compress(&cinfo);
+       if(file) fclose(file);
+       if(retval<0 && buf && *buf) {free(*buf);  *buf=NULL;}
+       return retval;
 }
 
-int savebmp(char *filename, unsigned char *buf, int w, int h,
-       enum BMPPIXELFORMAT f, int srcpitch, int srcbottomup)
+
+int savebmp(char *filename, unsigned char *buf, int w, int h, int srcpf,
+       int bottomup)
 {
-       int fd=-1, byteswritten, dstpitch, retcode=0;
-       int flags=O_RDWR|O_CREAT|O_TRUNC;
-       unsigned char *tempbuf=NULL;  char *temp;
-       bmphdr bh;  int mode;
-
-       #ifdef _WIN32
-       flags|=O_BINARY;  mode=_S_IREAD|_S_IWRITE;
-       #else
-       mode=S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
-       #endif
-       if(!filename || !buf || w<1 || h<1 || f<0 || f>BMPPIXELFORMATS-1 || srcpitch<0)
-               _throw("bad argument to savebmp()");
-
-       if(srcpitch==0) srcpitch=w*ps[f];
-
-       if((temp=strrchr(filename, '.'))!=NULL)
+       int retval=0, srcps, dstpf;
+       struct jpeg_decompress_struct dinfo;
+       struct my_error_mgr jerr;
+       djpeg_dest_ptr dst;
+       FILE *file=NULL;
+       char *ptr=NULL;
+
+       if(!filename || !buf || w<1 || h<1 || srcpf<0 || srcpf>=TJ_NUMPF)
+               _throw("savebmp(): Invalid argument");
+
+       if((file=fopen(filename, "wb"))==NULL)
+               _throwunix("savebmp(): Cannot open output file");
+
+       dinfo.err=jpeg_std_error(&jerr.pub);
+       jerr.pub.error_exit=my_error_exit;
+       jerr.pub.output_message=my_output_message;
+
+       if(setjmp(jerr.setjmp_buffer))
+       {
+               /* If we get here, the JPEG code has signaled an error. */
+               retval=-1;  goto bailout;
+       }
+
+       jpeg_create_decompress(&dinfo);
+       if(srcpf==TJPF_GRAY)
+       {
+               dinfo.out_color_components=dinfo.output_components=1;
+               dinfo.out_color_space=JCS_GRAYSCALE;
+       }
+       else
        {
-               if(!stricmp(temp, ".ppm"))
-                       return saveppm(filename, buf, w, h, f, srcpitch, srcbottomup);
+               dinfo.out_color_components=dinfo.output_components=3;
+               dinfo.out_color_space=JCS_RGB;
        }
+       dinfo.image_width=w;  dinfo.image_height=h;
+       dinfo.global_state=DSTATE_READY;
+       dinfo.scale_num=dinfo.scale_denom=1;
 
-       _unix(fd=open(filename, flags, mode));
-       dstpitch=((w*3)+3)&(~3);
-
-       bh.bfType=0x4d42;
-       bh.bfSize=BMPHDRSIZE+dstpitch*h;
-       bh.bfReserved1=0;  bh.bfReserved2=0;
-       bh.bfOffBits=BMPHDRSIZE;
-       bh.biSize=40;
-       bh.biWidth=w;  bh.biHeight=h;
-       bh.biPlanes=0;  bh.biBitCount=24;
-       bh.biCompression=BI_RGB;  bh.biSizeImage=0;
-       bh.biXPelsPerMeter=0;  bh.biYPelsPerMeter=0;
-       bh.biClrUsed=0;  bh.biClrImportant=0;
-
-       if(!littleendian())
+       ptr=strrchr(filename, '.');
+       if(ptr && !strcasecmp(ptr, ".bmp"))
+       {
+               if((dst=jinit_write_bmp(&dinfo, 0))==NULL)
+                       _throw("savebmp(): Could not initialize bitmap writer");
+       }
+       else
        {
-               bh.bfType=byteswap16(bh.bfType);
-               bh.bfSize=byteswap(bh.bfSize);
-               bh.bfOffBits=byteswap(bh.bfOffBits);
-               bh.biSize=byteswap(bh.biSize);
-               bh.biWidth=byteswap(bh.biWidth);
-               bh.biHeight=byteswap(bh.biHeight);
-               bh.biPlanes=byteswap16(bh.biPlanes);
-               bh.biBitCount=byteswap16(bh.biBitCount);
-               bh.biCompression=byteswap(bh.biCompression);
-               bh.biSizeImage=byteswap(bh.biSizeImage);
-               bh.biXPelsPerMeter=byteswap(bh.biXPelsPerMeter);
-               bh.biYPelsPerMeter=byteswap(bh.biYPelsPerMeter);
-               bh.biClrUsed=byteswap(bh.biClrUsed);
-               bh.biClrImportant=byteswap(bh.biClrImportant);
+               if((dst=jinit_write_ppm(&dinfo))==NULL)
+                       _throw("savebmp(): Could not initialize PPM writer");
        }
 
-       writeme(fd, &bh.bfType, sizeof(unsigned short));
-       writeme(fd, &bh.bfSize, sizeof(unsigned int));
-       writeme(fd, &bh.bfReserved1, sizeof(unsigned short));
-       writeme(fd, &bh.bfReserved2, sizeof(unsigned short));
-       writeme(fd, &bh.bfOffBits, sizeof(unsigned int));
-       writeme(fd, &bh.biSize, sizeof(unsigned int));
-       writeme(fd, &bh.biWidth, sizeof(int));
-       writeme(fd, &bh.biHeight, sizeof(int));
-       writeme(fd, &bh.biPlanes, sizeof(unsigned short));
-       writeme(fd, &bh.biBitCount, sizeof(unsigned short));
-       writeme(fd, &bh.biCompression, sizeof(unsigned int));
-       writeme(fd, &bh.biSizeImage, sizeof(unsigned int));
-       writeme(fd, &bh.biXPelsPerMeter, sizeof(int));
-       writeme(fd, &bh.biYPelsPerMeter, sizeof(int));
-       writeme(fd, &bh.biClrUsed, sizeof(unsigned int));
-       writeme(fd, &bh.biClrImportant, sizeof(unsigned int));
-
-       if((tempbuf=(unsigned char *)malloc(dstpitch*h))==NULL)
-               _throw("Memory allocation error");
-
-       pixelconvert(buf, f, srcpitch, tempbuf, BMP_BGR, dstpitch, w, h, 
-               !srcbottomup);
-
-       if((byteswritten=write(fd, tempbuf, dstpitch*h))!=dstpitch*h)
-               _throw(strerror(errno));
-
-       finally:
-       if(tempbuf) free(tempbuf);
-       if(fd!=-1) close(fd);
-       return retcode;
+  dst->output_file=file;
+       (*dst->start_output)(&dinfo, dst);
+       (*dinfo.mem->realize_virt_arrays)((j_common_ptr)&dinfo);
+
+       if(srcpf==TJPF_GRAY) dstpf=srcpf;
+       else dstpf=TJPF_RGB;
+       srcps=tjPixelSize[srcpf];
+
+       while(dinfo.output_scanline<dinfo.output_height)
+       {
+               int i, nlines=dst->buffer_height;
+               for(i=0; i<nlines; i++)
+               {
+                       unsigned char *inbuf;  int row;
+                       row=dinfo.output_scanline+i;
+                       if(bottomup) inbuf=&buf[(h-row-1)*w*srcps];
+                       else inbuf=&buf[row*w*srcps];
+                       pixelconvert(inbuf, srcpf, bottomup, dst->buffer[i], dstpf, 0, w,
+                               nlines);
+               }
+               (*dst->put_pixel_rows)(&dinfo, dst, nlines);
+               dinfo.output_scanline+=nlines;
+  }
+
+       (*dst->finish_output)(&dinfo, dst);
+
+       bailout:
+       jpeg_destroy_decompress(&dinfo);
+       if(file) fclose(file);
+       return retval;
 }
 
 const char *bmpgeterr(void)
 {
-       return __bmperr;
+       return errStr;
 }
diff --git a/bmp.h b/bmp.h
index 055b1eed9728dc663a07db65f3aee05e163211b1..0d1e4dca3b5c94729d73b98fcf3fb0338e2531bd 100644 (file)
--- a/bmp.h
+++ b/bmp.h
@@ -1,44 +1,41 @@
-/* Copyright (C)2004 Landmark Graphics Corporation
- * Copyright (C)2005 Sun Microsystems, Inc.
- * Copyright (C)2011 D. R. Commander
+/*
+ * Copyright (C)2011 D. R. Commander.  All Rights Reserved.
  *
- * This library is free software and may be redistributed and/or modified under
- * the terms of the wxWindows Library License, Version 3.1 or (at your option)
- * any later version.  The full license is in the LICENSE.txt file included
- * with this distribution.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
  *
- * This library 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
- * wxWindows Library License for more details.
-*/
-
-// This provides rudimentary facilities for loading and saving true color
-// BMP and PPM files
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of the libjpeg-turbo Project nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
 
 #ifndef __BMP_H__
 #define __BMP_H__
 
-#define BMPPIXELFORMATS 6
-enum BMPPIXELFORMAT {BMP_RGB=0, BMP_RGBX, BMP_BGR, BMP_BGRX, BMP_XBGR, BMP_XRGB};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// This will load a Windows bitmap from a file and return a buffer with the
-// specified pixel format, scanline alignment, and orientation.  The width and
-// height are returned in w and h.
-
-int loadbmp(char *filename, unsigned char **buf, int *w, int *h,
-       enum BMPPIXELFORMAT f, int align, int dstbottomup);
+#include "./turbojpeg.h"
 
-// This will save a buffer with the specified pixel format, pitch, orientation,
-// width, and height as a 24-bit Windows bitmap or PPM (the filename determines
-// which format to use)
+int loadbmp(char *filename, unsigned char **buf, int *w, int *h, int pf,
+       int bottomup);
 
-int savebmp(char *filename, unsigned char *buf, int w, int h,
-       enum BMPPIXELFORMAT f, int srcpitch, int srcbottomup);
+int savebmp(char *filename, unsigned char *buf, int w, int h, int pf,
+       int bottomup);
 
 const char *bmpgeterr(void);