diff --git a/CGAL_ImageIO/src/CGAL_ImageIO/gif.cpp b/CGAL_ImageIO/src/CGAL_ImageIO/gif.cpp index ffb865a3e76..c1735c610b4 100644 --- a/CGAL_ImageIO/src/CGAL_ImageIO/gif.cpp +++ b/CGAL_ImageIO/src/CGAL_ImageIO/gif.cpp @@ -19,640 +19,9 @@ // // Author(s) : ASCLEPIOS Project (INRIA Sophia-Antipolis), Laurent Rineau -#include +#ifndef CGAL_HEADER_ONLY #include "gif.h" +#include "gif_impl.h" -#ifdef WIN32 -#include -#endif - - - -/** Magic header for GIF files */ -#define GIF_MAGIC "GIF8" - - - -typedef unsigned char byte; -#define TRUE 1 -#define FALSE 0 - -#define NEXTBYTE (*ptr++) -#define EXTENSION 0x21 -#define IMAGESEP 0x2c -#define TRAILER 0x3b -#define INTERLACEMASK 0x40 -#define COLORMAPMASK 0x80 - - -#define DEBUG 0 - -FILE *fp; -int gif89 = 0; -const char *id87 = "GIF87a"; -const char *id89 = "GIF89a"; - -static int EGApalette[16][3] = { - {0,0,0}, {0,0,128}, {0,128,0}, {0,128,128}, - {128,0,0}, {128,0,128}, {128,128,0}, {200,200,200}, - {100,100,100}, {100,100,255}, {100,255,100}, {100,255,255}, - {255,100,100}, {255,100,255}, {255,255,100}, {255,255,255} }; - - -static int ReadCode(); -static void DoInterlace(byte); -static int GifError(const char *); - - -byte *Raster; /* The raster data stream, unblocked */ -byte *RawGIF; -byte *r,*g,*b; /* The colormap */ -int BitOffset = 0, /* Bit Offset of next code */ - XC = 0, YC = 0, /* Output X and Y coords of current pixel */ - CodeSize, /* Code size, read from GIF header */ - ReadMask, /* Code AND mask for current code size */ - Pass = 0, /* Used by output routine if interlaced pic */ - Width, Height; /* image dimensions */ - -unsigned char *org, *buf; - -int testGifHeader(char *magic,const char *) { - if (!strcmp(magic, GIF_MAGIC)) - return 0; - else - return -1; -} -PTRIMAGE_FORMAT createGifFormat() { - PTRIMAGE_FORMAT f=(PTRIMAGE_FORMAT) ImageIO_alloc(sizeof(IMAGE_FORMAT)); - - f->testImageFormat=&testGifHeader; - f->readImageHeader=&readGifImage; - f->writeImage=0; - strcpy(f->fileExtension,".gif"); - strcpy(f->realName,"Gif"); - return f; -} - -void use(int) {} // warning killer - -/*****************************/ -int readGifImage(const char *name,_image *im) { - register byte ch, ch1; - register byte *ptr, *ptr1; - register int i, block; - int npixels, maxpixels, aspect, filesize; - float normaspect; - int OutCount = 0, /* Decompressor output 'stack count' */ - RWidth, RHeight, /* screen dimensions */ - /*LeftOfs, TopOfs, image offset */ - BitsPerPixel, /* Bits per pixel, read from GIF header */ - ColorMapSize, /* number of colors */ - Background, /* background color */ - InitCodeSize, /* Starting code size, used during Clear */ - Code, /* Value returned by ReadCode */ - MaxCode, /* limiting value for current code size */ - ClearCode, /* GIF clear code */ - EOFCode, /* GIF end-of-information code */ - CurCode, OldCode=0, InCode, /* Decompressor variables */ - FirstFree, /* First free code, generated per GIF spec */ - FreeCode, /* Decompressor,next free slot in hash table */ - FinChar=0, /* Decompressor variable */ - BitMask, /* AND mask for data size */ - Misc; /* miscellaneous bits (interlace, local cmap)*/ - int Interlace, HasColormap; - /* not used - */ - /* char header[10]; */ - - /* The hash table used by the decompressor */ - int Prefix[4096]; - int Suffix[4096]; - /* An output array used by the decompressor */ - int OutCode[4097]; - - /* initialize variables */ - BitOffset = XC = YC = Pass = OutCount = npixels = maxpixels = 0; - RawGIF = Raster = NULL; - gif89 = 0; - -#ifdef WIN32 - fp = fopen(name,"rb"); -#else - fp = fopen(name,"r"); -#endif - fp = fopen(name,"rb"); - if (!fp) { - return(GifError("could not open a GIF file")); - } - /* find the size of the file */ - fseek(fp, 0L, 2); - filesize = ftell(fp); - fseek(fp, 0L, 0); - - /* the +256's are so we can read truncated GIF files without fear of - segmentation violation */ - if (!(ptr = RawGIF = (byte *) ImageIO_alloc(filesize+256))) - return( GifError("not enough memory to read gif file") ); - - if (!(Raster = (byte *) ImageIO_alloc(filesize+256))) - return( GifError("not enough memory to read gif file") ); - - if (fread(ptr, filesize, 1, fp) != 1) - return( GifError("GIF data read failed") ); - if (strncmp((char *) ptr, id87, 6)==0) gif89 = 0; - else if (strncmp((char *) ptr, id89, 6)==0) gif89 = 1; - else return( GifError("not a GIF file")); - - ptr += 6; - /* Get variables from the GIF screen descriptor */ - - ch = NEXTBYTE; - RWidth = ch + 0x100 * NEXTBYTE; /* screen dimensions... not used. */ - ch = NEXTBYTE; - RHeight = ch + 0x100 * NEXTBYTE; - use(RWidth); - use(RHeight); - - ch = NEXTBYTE; - HasColormap = ((ch & COLORMAPMASK) ? TRUE : FALSE); - - BitsPerPixel = (ch & 7) + 1; - ColorMapSize = 1 << BitsPerPixel; - BitMask = ColorMapSize - 1; - - Background = NEXTBYTE; /* background color... not used. */ - use(Background); - - - aspect = NEXTBYTE; - if (aspect) { - if (!gif89) return(GifError("corrupt GIF file (screen descriptor)")); - else normaspect = (float) (aspect + 15) / 64.0f; /* gif89 aspect ratio */ - if (DEBUG) fprintf(stderr,"GIF89 aspect = %f\n", normaspect); - } - - - /* Read in global colormap. */ - if (HasColormap) - { - r = (byte *) ImageIO_alloc(ColorMapSize * sizeof(byte)); - g = (byte *) ImageIO_alloc(ColorMapSize * sizeof(byte)); - b = (byte *) ImageIO_alloc(ColorMapSize * sizeof(byte)); - - for (i = 0; i < ColorMapSize; i++) { - r[i] = NEXTBYTE; - g[i] = NEXTBYTE; - b[i] = NEXTBYTE; - } - } - else { - /* no colormap in GIF file */ - /* put std EGA palette (repeated 16 times) into colormap, for lack of - anything better to do */ - ColorMapSize = 256; - r = (byte *) ImageIO_alloc(256 * sizeof(byte)); - g = (byte *) ImageIO_alloc(256 * sizeof(byte)); - b = (byte *) ImageIO_alloc(256 * sizeof(byte)); - - for (i = 0; i < 256; i++) { - r[i] = EGApalette[i&15][0]; - g[i] = EGApalette[i&15][1]; - b[i] = EGApalette[i&15][2]; - } - } - - /* possible things at this point are: - * an application extension block - * a comment extension block - * an (optional) graphic control extension block - * followed by either an image - * or a plaintext extension - */ - while (1) { - block = NEXTBYTE; - - if (block == EXTENSION) { /* parse extension blocks */ - int i, fn, blocksize, aspnum, aspden; - - /* read extension block */ - fn = NEXTBYTE; - - if (DEBUG) fprintf(stderr,"GIF extension type 0x%02x\n", fn); - - if (fn == 'R') { /* GIF87 aspect extension */ - blocksize = NEXTBYTE; - if (blocksize == 2) { - aspnum = NEXTBYTE; - aspden = NEXTBYTE; - if (aspden>0 && aspnum>0) - normaspect = (float) aspnum / (float) aspden; - else { normaspect = 1.0; aspnum = aspden = 1; } - - if (DEBUG) fprintf(stderr,"GIF87 aspect extension: %d:%d = %f\n\n", - aspnum, aspden,normaspect); - } - else { - for (i=0; i filesize) { - /* SetISTR(ISTR_WARNING, - "This GIF file seems to be truncated. Winging it.");*/ - break; - } - } while(ch1); - ImageIO_free(RawGIF); RawGIF = NULL; - - - if (DEBUG) { - fprintf(stderr,"xv: LoadGIF() - picture is %dx%d, %d bits, %sinterlaced\n", - Width, Height, BitsPerPixel, Interlace ? "" : "non-"); - } - - - /* Allocate the 'pic' */ - maxpixels = Width*Height; - im->xdim = Width; - im->ydim = Height; - im->zdim = 1; - im->vdim = 3; - im->wdim = 1; - im->wordKind = WK_FIXED; - im->sign = SGN_UNSIGNED; - im->data = ImageIO_alloc(Width * Height * 3); - org = buf = (unsigned char *) im->data; - - if (!org) - return( GifError("not enough memory for image buffer") ); - - - /* Decompress the file, continuing until you see the GIF EOF code. - * One obvious enhancement is to add checking for corrupt files here. - */ - Code = ReadCode(); - while (Code != EOFCode) { - /* Clear code sets everything back to its initial value, then reads the - * immediately subsequent code as uncompressed data. - */ - - if (Code == ClearCode) { - CodeSize = InitCodeSize; - MaxCode = (1 << CodeSize); - ReadMask = MaxCode - 1; - FreeCode = FirstFree; - Code = ReadCode(); - CurCode = OldCode = Code; - FinChar = CurCode & BitMask; - if (!Interlace) { - *buf++ = r[FinChar]; - *buf++ = g[FinChar]; - *buf++ = b[FinChar]; - } - else DoInterlace((byte)FinChar); - npixels++; - } - - else { - /* If not a clear code, must be data: save same as CurCode and InCode */ - - /* if we're at maxcode and didn't get a clear, stop loading */ - if (FreeCode>=4096) { - printf("freecode blew up\n"); - break; - } - - CurCode = InCode = Code; - - /* If greater or equal to FreeCode, not in the hash table yet; - * repeat the last character decoded - */ - - if (CurCode >= FreeCode) { - CurCode = OldCode; - if (OutCount > 4096) { - printf("outcount1 blew up\n"); break; } - OutCode[OutCount++] = FinChar; - } - - /* Unless this code is raw data, pursue the chain pointed to by CurCode - * through the hash table to its end; each code in the chain puts its - * associated output code on the output queue. - */ - - while (CurCode > BitMask) { - if (OutCount > 4096) { - fprintf(stderr,"outcount2 blew up\n"); break;} /* corrupt file */ - OutCode[OutCount++] = Suffix[CurCode]; - CurCode = Prefix[CurCode]; - } - - if (OutCount > 4096) { - printf("outcount blew up\n"); break; } - - /* The last code in the chain is treated as raw data. */ - - FinChar = CurCode & BitMask; - OutCode[OutCount++] = FinChar; - - /* Now we put the data out to the Output routine. - * It's been stacked LIFO, so deal with it that way... - */ - - /* safety thing: prevent exceeding range of 'pic' */ - if (npixels + OutCount > maxpixels) OutCount = maxpixels-npixels; - - npixels += OutCount; - if (!Interlace) for (i=OutCount-1; i>=0; i--) { - *buf++ = r[OutCode[i]]; - *buf++ = g[OutCode[i]]; - *buf++ = b[OutCode[i]]; - } - else for (i=OutCount-1; i>=0; i--) DoInterlace((byte)OutCode[i]); - OutCount = 0; - - /* Build the hash table on-the-fly. No table is stored in the file. */ - - Prefix[FreeCode] = OldCode; - Suffix[FreeCode] = FinChar; - OldCode = InCode; - - /* Point to the next slot in the table. If we exceed the current - * MaxCode value, increment the code size unless it's already 12. If it - * is, do nothing: the next code decompressed better be CLEAR - */ - - FreeCode++; - if (FreeCode >= MaxCode) { - if (CodeSize < 12) { - CodeSize++; - MaxCode *= 2; - ReadMask = (1 << CodeSize) - 1; - } - } - } - Code = ReadCode(); - if (npixels >= maxpixels) break; - } - ImageIO_free(Raster); Raster = NULL; - - if (npixels != maxpixels) { - /* SetISTR(ISTR_WARNING,"This GIF file seems to be truncated. Winging it.");*/ - if (!Interlace) - memset(buf, 0, 3*(maxpixels-npixels)); /* clear to EOBuffer */ - } - /* SetDirRButt(F_FORMAT, F_GIF); - SetDirRButt(F_COLORS, F_FULLCOLOR);*/ - return 1; -} - - -/* Fetch the next code from the raster data stream. The codes can be - * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to - * maintain our location in the Raster array as a BIT Offset. We compute - * the byte Offset into the raster array by dividing this by 8, pick up - * three bytes, compute the bit Offset into our 24-bit chunk, shift to - * bring the desired code to the bottom, then mask it off and return it. - */ - -static int ReadCode() -{ - int RawCode, ByteOffset; - - ByteOffset = BitOffset / 8; - RawCode = Raster[ByteOffset] + (Raster[ByteOffset + 1] << 8); - if (CodeSize >= 8) - RawCode += ( ((int) Raster[ByteOffset + 2]) << 16); - RawCode >>= (BitOffset % 8); - BitOffset += CodeSize; - - return(RawCode & ReadMask); -} - - -/***************************/ -static void DoInterlace(byte Index) { - static byte *ptr = NULL; - static int oldYC = -1; - - if (oldYC != YC) { - ptr = org + 3 * YC * Width; - oldYC = YC; - } - - if (YC < Height) { - *ptr++ = r[Index]; - *ptr++ = g[Index]; - *ptr++ = b[Index]; - } - - /* Update the X-coordinate, and if it overflows, update the Y-coordinate */ - if (++XC == Width) { - - /* deal with the interlace as described in the GIF - * spec. Put the decoded scan line out to the screen if we haven't gone - * past the bottom of it - */ - - XC = 0; - - switch (Pass) { - case 0: - YC += 8; - if (YC >= Height) { Pass++; YC = 4; } - break; - - case 1: - YC += 8; - if (YC >= Height) { Pass++; YC = 2; } - break; - - case 2: - YC += 4; - if (YC >= Height) { Pass++; YC = 1; } - break; - - case 3: - YC += 2; break; - - default: - break; - } - } -} - - - -/*****************************/ -static int GifError(const char *st) { - fprintf(stderr,"readGifImage: error: %s\n",st); - - if (RawGIF != NULL) ImageIO_free(RawGIF); - if (Raster != NULL) ImageIO_free(Raster); - - return -1; -} - +#endif // CGAL_HEADER_ONLY diff --git a/CGAL_ImageIO/src/CGAL_ImageIO/gif.h b/CGAL_ImageIO/src/CGAL_ImageIO/gif.h index a3612201c34..467f9183f2a 100644 --- a/CGAL_ImageIO/src/CGAL_ImageIO/gif.h +++ b/CGAL_ImageIO/src/CGAL_ImageIO/gif.h @@ -31,5 +31,8 @@ int testGifHeader(char *magic,const char *name); /** creates an return the file format structure associated with the Gif file format */ PTRIMAGE_FORMAT createGifFormat(); +#ifdef CGAL_HEADER_ONLY +#include "gif_impl.h" +#endif // CGAL_HEADER_ONLY #endif diff --git a/CGAL_ImageIO/src/CGAL_ImageIO/gif_impl.h b/CGAL_ImageIO/src/CGAL_ImageIO/gif_impl.h new file mode 100644 index 00000000000..994ea09fe39 --- /dev/null +++ b/CGAL_ImageIO/src/CGAL_ImageIO/gif_impl.h @@ -0,0 +1,699 @@ +// Copyright (c) 2005-2008 ASCLEPIOS Project, INRIA Sophia-Antipolis (France) +// All rights reserved. +// +// This file is part of the ImageIO Library, and as been adapted for +// CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the +// GNU Lesser General Public License as published by the Free Software Foundation; +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// These files are provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : ASCLEPIOS Project (INRIA Sophia-Antipolis), Laurent Rineau + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include + +#ifdef WIN32 +#include +#endif + +#ifdef CGAL_HEADER_ONLY + + #define CGAL_GLOBAL_STATE_VAR(TYPE, NAME, VALUE) \ + inline TYPE & get_static_##NAME() \ + { \ + static TYPE NAME = VALUE; \ + return NAME; \ + } + +#else // CGAL_HEADER_ONLY + + #define CGAL_GLOBAL_STATE_VAR(TYPE, NAME, VALUE) \ + TYPE NAME; \ + inline TYPE& get_static_##NAME() \ + { \ + return NAME; \ + } + +#endif // CGAL_HEADER_ONLY + + +/** Magic header for GIF files */ +#define GIF_MAGIC "GIF8" + + + +typedef unsigned char byte; +#define TRUE 1 +#define FALSE 0 + +#define NEXTBYTE (*ptr++) +#define EXTENSION 0x21 +#define IMAGESEP 0x2c +#define TRAILER 0x3b +#define INTERLACEMASK 0x40 +#define COLORMAPMASK 0x80 + + +#define DEBUG 0 + +//FILE *fp; +//int gif89 = 0; +const char *id87 = "GIF87a"; +const char *id89 = "GIF89a"; + +static int EGApalette[16][3] = { + {0,0,0}, {0,0,128}, {0,128,0}, {0,128,128}, + {128,0,0}, {128,0,128}, {128,128,0}, {200,200,200}, + {100,100,100}, {100,100,255}, {100,255,100}, {100,255,255}, + {255,100,100}, {255,100,255}, {255,255,100}, {255,255,255} }; + + +static int ReadCode(); +static void DoInterlace(byte); +static int GifError(const char *); + +CGAL_GLOBAL_STATE_VAR(byte *, Raster, NULL) /* The raster data stream, unblocked */ +CGAL_GLOBAL_STATE_VAR(byte *, RawGIF, NULL) +CGAL_GLOBAL_STATE_VAR(byte *, r, NULL) +CGAL_GLOBAL_STATE_VAR(byte *, g, NULL) +CGAL_GLOBAL_STATE_VAR(byte *, b, NULL) /* The colormap */ +CGAL_GLOBAL_STATE_VAR(int, BitOffset, 0) /* Bit Offset of next code */ +CGAL_GLOBAL_STATE_VAR(int, XC, 0) +CGAL_GLOBAL_STATE_VAR(int, YC, 0) /* Output X and Y coords of current pixel */ +CGAL_GLOBAL_STATE_VAR(int, CodeSize, 0) /* Code size, read from GIF header */ +CGAL_GLOBAL_STATE_VAR(int, ReadMask, 0) /* Code AND mask for current code size */ +CGAL_GLOBAL_STATE_VAR(int, Pass, 0) /* Used by output routine if interlaced pic */ +CGAL_GLOBAL_STATE_VAR(int, Width, 0) +CGAL_GLOBAL_STATE_VAR(int, Height, 0) /* image dimensions */ +CGAL_GLOBAL_STATE_VAR(unsigned char *, org, NULL) +CGAL_GLOBAL_STATE_VAR(unsigned char *, buf, NULL) + +CGAL_INLINE_FUNCTION +int testGifHeader(char *magic,const char *) { + if (!strcmp(magic, GIF_MAGIC)) + return 0; + else + return -1; +} +CGAL_INLINE_FUNCTION +PTRIMAGE_FORMAT createGifFormat() { + PTRIMAGE_FORMAT f=(PTRIMAGE_FORMAT) ImageIO_alloc(sizeof(IMAGE_FORMAT)); + + f->testImageFormat=&testGifHeader; + f->readImageHeader=&readGifImage; + f->writeImage=0; + strcpy(f->fileExtension,".gif"); + strcpy(f->realName,"Gif"); + return f; +} + +void use(int) {} // warning killer + +/*****************************/ +CGAL_INLINE_FUNCTION +int readGifImage(const char *name,_image *im) { +FILE *fp; +int gif89 = 0; + + register byte ch, ch1; + register byte *ptr, *ptr1; + register int i, block; + int npixels, maxpixels, aspect, filesize; + float normaspect; + int OutCount = 0, /* Decompressor output 'stack count' */ + RWidth, RHeight, /* screen dimensions */ + /*LeftOfs, TopOfs, image offset */ + BitsPerPixel, /* Bits per pixel, read from GIF header */ + ColorMapSize, /* number of colors */ + Background, /* background color */ + InitCodeSize, /* Starting code size, used during Clear */ + Code, /* Value returned by ReadCode */ + MaxCode, /* limiting value for current code size */ + ClearCode, /* GIF clear code */ + EOFCode, /* GIF end-of-information code */ + CurCode, OldCode=0, InCode, /* Decompressor variables */ + FirstFree, /* First free code, generated per GIF spec */ + FreeCode, /* Decompressor,next free slot in hash table */ + FinChar=0, /* Decompressor variable */ + BitMask, /* AND mask for data size */ + Misc; /* miscellaneous bits (interlace, local cmap)*/ + int Interlace, HasColormap; + /* not used + */ + /* char header[10]; */ + + /* The hash table used by the decompressor */ + int Prefix[4096]; + int Suffix[4096]; + /* An output array used by the decompressor */ + int OutCode[4097]; + + /* initialize variables */ + get_static_BitOffset() = + get_static_XC() = + get_static_YC() = + get_static_Pass() = + OutCount = + npixels = + maxpixels = 0; + get_static_RawGIF() = get_static_Raster() = NULL; + gif89 = 0; + +#ifdef WIN32 + fp = fopen(name,"rb"); +#else + fp = fopen(name,"r"); +#endif + fp = fopen(name,"rb"); + if (!fp) { + return(GifError("could not open a GIF file")); + } + /* find the size of the file */ + fseek(fp, 0L, 2); + filesize = ftell(fp); + fseek(fp, 0L, 0); + + /* the +256's are so we can read truncated GIF files without fear of + segmentation violation */ + if (!(ptr = get_static_RawGIF() = (byte *) ImageIO_alloc(filesize+256))) + return( GifError("not enough memory to read gif file") ); + + if (!(get_static_Raster() = (byte *) ImageIO_alloc(filesize+256))) + return( GifError("not enough memory to read gif file") ); + + if (fread(ptr, filesize, 1, fp) != 1) + return( GifError("GIF data read failed") ); + if (strncmp((char *) ptr, id87, 6)==0) gif89 = 0; + else if (strncmp((char *) ptr, id89, 6)==0) gif89 = 1; + else return( GifError("not a GIF file")); + + ptr += 6; + /* Get variables from the GIF screen descriptor */ + + ch = NEXTBYTE; + RWidth = ch + 0x100 * NEXTBYTE; /* screen dimensions... not used. */ + ch = NEXTBYTE; + RHeight = ch + 0x100 * NEXTBYTE; + use(RWidth); + use(RHeight); + + ch = NEXTBYTE; + HasColormap = ((ch & COLORMAPMASK) ? TRUE : FALSE); + + BitsPerPixel = (ch & 7) + 1; + ColorMapSize = 1 << BitsPerPixel; + BitMask = ColorMapSize - 1; + + Background = NEXTBYTE; /* background color... not used. */ + use(Background); + + + aspect = NEXTBYTE; + if (aspect) { + if (!gif89) return(GifError("corrupt GIF file (screen descriptor)")); + else normaspect = (float) (aspect + 15) / 64.0f; /* gif89 aspect ratio */ + if (DEBUG) fprintf(stderr,"GIF89 aspect = %f\n", normaspect); + } + + + /* Read in global colormap. */ + if (HasColormap) + { + get_static_r() = (byte *) ImageIO_alloc(ColorMapSize * sizeof(byte)); + get_static_g() = (byte *) ImageIO_alloc(ColorMapSize * sizeof(byte)); + get_static_b() = (byte *) ImageIO_alloc(ColorMapSize * sizeof(byte)); + + for (i = 0; i < ColorMapSize; i++) { + get_static_r()[i] = NEXTBYTE; + get_static_g()[i] = NEXTBYTE; + get_static_b()[i] = NEXTBYTE; + } + } + else { + /* no colormap in GIF file */ + /* put std EGA palette (repeated 16 times) into colormap, for lack of + anything better to do */ + ColorMapSize = 256; + get_static_r() = (byte *) ImageIO_alloc(256 * sizeof(byte)); + get_static_g() = (byte *) ImageIO_alloc(256 * sizeof(byte)); + get_static_b() = (byte *) ImageIO_alloc(256 * sizeof(byte)); + + for (i = 0; i < 256; i++) { + get_static_r()[i] = EGApalette[i&15][0]; + get_static_g()[i] = EGApalette[i&15][1]; + get_static_b()[i] = EGApalette[i&15][2]; + } + } + + /* possible things at this point are: + * an application extension block + * a comment extension block + * an (optional) graphic control extension block + * followed by either an image + * or a plaintext extension + */ + while (1) { + block = NEXTBYTE; + + if (block == EXTENSION) { /* parse extension blocks */ + int i, fn, blocksize, aspnum, aspden; + + /* read extension block */ + fn = NEXTBYTE; + + if (DEBUG) fprintf(stderr,"GIF extension type 0x%02x\n", fn); + + if (fn == 'R') { /* GIF87 aspect extension */ + blocksize = NEXTBYTE; + if (blocksize == 2) { + aspnum = NEXTBYTE; + aspden = NEXTBYTE; + if (aspden>0 && aspnum>0) + normaspect = (float) aspnum / (float) aspden; + else { normaspect = 1.0; aspnum = aspden = 1; } + + if (DEBUG) fprintf(stderr,"GIF87 aspect extension: %d:%d = %f\n\n", + aspnum, aspden,normaspect); + } + else { + for (i=0; i filesize) { + /* SetISTR(ISTR_WARNING, + "This GIF file seems to be truncated. Winging it.");*/ + break; + } + } while(ch1); + ImageIO_free(get_static_RawGIF()); get_static_RawGIF() = NULL; + + + if (DEBUG) { + fprintf(stderr,"xv: LoadGIF() - picture is %dx%d, %d bits, %sinterlaced\n", + get_static_Width(), get_static_Height(), BitsPerPixel, Interlace ? "" : "non-"); + } + + + /* Allocate the 'pic' */ + maxpixels = get_static_Width()*get_static_Height(); + im->xdim = get_static_Width(); + im->ydim = get_static_Height(); + im->zdim = 1; + im->vdim = 3; + im->wdim = 1; + im->wordKind = WK_FIXED; + im->sign = SGN_UNSIGNED; + im->data = ImageIO_alloc(get_static_Width() * get_static_Height() * 3); + get_static_org() = get_static_buf() = (unsigned char *) im->data; + + if (!get_static_org()) + return( GifError("not enough memory for image buffer") ); + + + /* Decompress the file, continuing until you see the GIF EOF code. + * One obvious enhancement is to add checking for corrupt files here. + */ + Code = ReadCode(); + while (Code != EOFCode) { + /* Clear code sets everything back to its initial value, then reads the + * immediately subsequent code as uncompressed data. + */ + + if (Code == ClearCode) { + get_static_CodeSize() = InitCodeSize; + MaxCode = (1 << get_static_CodeSize()); + get_static_ReadMask() = MaxCode - 1; + FreeCode = FirstFree; + Code = ReadCode(); + CurCode = OldCode = Code; + FinChar = CurCode & BitMask; + if (!Interlace) { + *get_static_buf()++ = get_static_r()[FinChar]; + *get_static_buf()++ = get_static_g()[FinChar]; + *get_static_buf()++ = get_static_b()[FinChar]; + } + else DoInterlace((byte)FinChar); + npixels++; + } + + else { + /* If not a clear code, must be data: save same as CurCode and InCode */ + + /* if we're at maxcode and didn't get a clear, stop loading */ + if (FreeCode>=4096) { + printf("freecode blew up\n"); + break; + } + + CurCode = InCode = Code; + + /* If greater or equal to FreeCode, not in the hash table yet; + * repeat the last character decoded + */ + + if (CurCode >= FreeCode) { + CurCode = OldCode; + if (OutCount > 4096) { + printf("outcount1 blew up\n"); break; } + OutCode[OutCount++] = FinChar; + } + + /* Unless this code is raw data, pursue the chain pointed to by CurCode + * through the hash table to its end; each code in the chain puts its + * associated output code on the output queue. + */ + + while (CurCode > BitMask) { + if (OutCount > 4096) { + fprintf(stderr,"outcount2 blew up\n"); break;} /* corrupt file */ + OutCode[OutCount++] = Suffix[CurCode]; + CurCode = Prefix[CurCode]; + } + + if (OutCount > 4096) { + printf("outcount blew up\n"); break; } + + /* The last code in the chain is treated as raw data. */ + + FinChar = CurCode & BitMask; + OutCode[OutCount++] = FinChar; + + /* Now we put the data out to the Output routine. + * It's been stacked LIFO, so deal with it that way... + */ + + /* safety thing: prevent exceeding range of 'pic' */ + if (npixels + OutCount > maxpixels) OutCount = maxpixels-npixels; + + npixels += OutCount; + if (!Interlace) for (i=OutCount-1; i>=0; i--) { + *get_static_buf()++ = get_static_r()[OutCode[i]]; + *get_static_buf()++ = get_static_g()[OutCode[i]]; + *get_static_buf()++ = get_static_b()[OutCode[i]]; + } + else for (i=OutCount-1; i>=0; i--) DoInterlace((byte)OutCode[i]); + OutCount = 0; + + /* Build the hash table on-the-fly. No table is stored in the file. */ + + Prefix[FreeCode] = OldCode; + Suffix[FreeCode] = FinChar; + OldCode = InCode; + + /* Point to the next slot in the table. If we exceed the current + * MaxCode value, increment the code size unless it's already 12. If it + * is, do nothing: the next code decompressed better be CLEAR + */ + + FreeCode++; + if (FreeCode >= MaxCode) { + if (get_static_CodeSize() < 12) { + get_static_CodeSize()++; + MaxCode *= 2; + get_static_ReadMask() = (1 << get_static_CodeSize()) - 1; + } + } + } + Code = ReadCode(); + if (npixels >= maxpixels) break; + } + ImageIO_free(get_static_Raster()); get_static_Raster() = NULL; + + if (npixels != maxpixels) { + /* SetISTR(ISTR_WARNING,"This GIF file seems to be truncated. Winging it.");*/ + if (!Interlace) + memset(get_static_buf(), 0, 3*(maxpixels-npixels)); /* clear to EOBuffer */ + } + /* SetDirRButt(F_FORMAT, F_GIF); + SetDirRButt(F_COLORS, F_FULLCOLOR);*/ + return 1; +} + + +/* Fetch the next code from the raster data stream. The codes can be + * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to + * maintain our location in the Raster array as a BIT Offset. We compute + * the byte Offset into the raster array by dividing this by 8, pick up + * three bytes, compute the bit Offset into our 24-bit chunk, shift to + * bring the desired code to the bottom, then mask it off and return it. + */ + +CGAL_INLINE_FUNCTION +static int ReadCode() +{ + int RawCode, ByteOffset; + + ByteOffset = get_static_BitOffset() / 8; + RawCode = get_static_Raster()[ByteOffset] + (get_static_Raster()[ByteOffset + 1] << 8); + if (get_static_CodeSize() >= 8) + RawCode += ( ((int) get_static_Raster()[ByteOffset + 2]) << 16); + RawCode >>= (get_static_BitOffset() % 8); + get_static_BitOffset() += get_static_CodeSize(); + + return(RawCode & get_static_ReadMask()); +} + + +/***************************/ +CGAL_INLINE_FUNCTION +static void DoInterlace(byte Index) { + static byte *ptr = NULL; + static int oldYC = -1; + + if (oldYC != get_static_YC()) { + ptr = get_static_org() + 3 * get_static_YC() * get_static_Width(); + oldYC = get_static_YC(); + } + + if (get_static_YC() < get_static_Height()) { + *ptr++ = get_static_r()[Index]; + *ptr++ = get_static_g()[Index]; + *ptr++ = get_static_b()[Index]; + } + + /* Update the X-coordinate, and if it overflows, update the Y-coordinate */ + if (++get_static_XC() == get_static_Width()) { + + /* deal with the interlace as described in the GIF + * spec. Put the decoded scan line out to the screen if we haven't gone + * past the bottom of it + */ + + get_static_XC() = 0; + + switch (get_static_Pass()) { + case 0: + get_static_YC() += 8; + if (get_static_YC() >= get_static_Height()) { get_static_Pass()++; get_static_YC() = 4; } + break; + + case 1: + get_static_YC() += 8; + if (get_static_YC() >= get_static_Height()) { get_static_Pass()++; get_static_YC() = 2; } + break; + + case 2: + get_static_YC() += 4; + if (get_static_YC() >= get_static_Height()) { get_static_Pass()++; get_static_YC() = 1; } + break; + + case 3: + get_static_YC() += 2; break; + + default: + break; + } + } +} + + + +/*****************************/ +CGAL_INLINE_FUNCTION +static int GifError(const char *st) { + fprintf(stderr,"readGifImage: error: %s\n",st); + + if (get_static_RawGIF() != NULL) ImageIO_free(get_static_RawGIF()); + if (get_static_Raster() != NULL) ImageIO_free(get_static_Raster()); + + return -1; +} + diff --git a/CGAL_ImageIO/src/CGAL_ImageIO/gis.h b/CGAL_ImageIO/src/CGAL_ImageIO/gis.h index 1bfabb6f744..d1146854e51 100644 --- a/CGAL_ImageIO/src/CGAL_ImageIO/gis.h +++ b/CGAL_ImageIO/src/CGAL_ImageIO/gis.h @@ -134,5 +134,8 @@ int writeGisHeader( const _image* im ) ; */ int writeGisData( const _image* im ) ; +#ifdef CGAL_HEADER_ONLY +#include "gis.h" +#endif // CGAL_HEADER_ONLY #endif diff --git a/CGAL_ImageIO/src/CGAL_ImageIO/gis_impl.h b/CGAL_ImageIO/src/CGAL_ImageIO/gis_impl.h new file mode 100644 index 00000000000..4c823782c17 --- /dev/null +++ b/CGAL_ImageIO/src/CGAL_ImageIO/gis_impl.h @@ -0,0 +1,729 @@ +// Copyright (c) 2005-2008 ASCLEPIOS Project, INRIA Sophia-Antipolis (France) +// All rights reserved. +// +// This file is part of the ImageIO Library, and as been adapted for +// CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the +// GNU Lesser General Public License as published by the Free Software Foundation; +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// These files are provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : ASCLEPIOS Project (INRIA Sophia-Antipolis), Laurent Rineau + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include +#include + +#include "inr.h" +#include "fgetns.h" + +#define _LGTH_STRING_ 1024 + +CGAL_INLINE_FUNCTION +PTRIMAGE_FORMAT createGisFormat() { + PTRIMAGE_FORMAT f=(PTRIMAGE_FORMAT) ImageIO_alloc(sizeof(IMAGE_FORMAT)); + + f->testImageFormat=&testGisHeader; + f->readImageHeader=&readGisHeader; + f->writeImage=&writeGis; + strcpy(f->fileExtension,".dim,.dim.gz,.ima,.ima.gz"); + strcpy(f->realName,"Gis"); + return f; +} +CGAL_INLINE_FUNCTION +int writeGis( char *name, _image* im) { + char *outputName; + int length, extLength=0, res; + + + length=strlen(name); + outputName= (char *)ImageIO_alloc(length+8); + + if ( strncmp( name+length-4, ".dim", 4 ) == 0 ) { + extLength = 4; + } + else if ( strncmp( name+length-4, ".ima", 4 ) == 0 ) { + extLength = 4; + } + else if ( strncmp( name+length-7, ".ima.gz", 7 ) == 0 ) { + extLength = 7; + } + else if ( strncmp( name+length-7, ".dim.gz", 7 ) == 0 ) { + extLength = 7; + } + + strncpy( outputName, name, length-extLength ); + if ( strncmp( name+length-7, ".dim.gz", 7 ) == 0 ) + strcpy( outputName+length-extLength, ".dim.gz" ); + else + strcpy( outputName+length-extLength, ".dim" ); + + _openWriteImage(im, outputName); + if( !im->fd ) { + fprintf(stderr, "writeGis: error: unable to open file \'%s\'\n", outputName); + if ( outputName != NULL ) ImageIO_free( outputName ); + return ImageIO_OPENING; + } + + res = writeGisHeader(im); + if (res < 0 ) { + fprintf(stderr, "writeGis: error: unable to write header of \'%s\'\n", + outputName); + if ( outputName != NULL ) ImageIO_free( outputName ); + ImageIO_close( im ); + im->fd = NULL; + im->openMode = OM_CLOSE; + return( res ); + } + + ImageIO_close(im); + + strncpy( outputName, name, length-extLength ); + if ( strncmp( name+length-3, ".gz", 3 ) == 0 ) { + strcpy( outputName+length-extLength, ".ima.gz" ); + } + else { + strcpy( outputName+length-extLength, ".ima" ); + } + + _openWriteImage(im, outputName); + + if( !im->fd ) { + fprintf(stderr, "writeGis: error: unable to open file \'%s\'\n", outputName); + if ( outputName != NULL ) ImageIO_free( outputName ); + return ImageIO_OPENING; + } + + if ( im->dataMode == DM_ASCII ) { + int i, j, n, size; + char *str = (char*)ImageIO_alloc( _LGTH_STRING_+1 ); + size = im->xdim * im->ydim * im->zdim * im->vdim; + n = ( im->xdim < 16 ) ? im->xdim : 16; + i = 0; + + switch( im->wordKind ) { + default : + fprintf(stderr, "writeGis: such word kind not handled in ascii mode for file \'%s\'\n", outputName); + if ( outputName != NULL ) ImageIO_free( outputName ); + return( -3 ); + case WK_FIXED : + switch ( im->wdim ) { + default : + fprintf(stderr, "writeGis: such word dim not handled in ascii mode for file \'%s\'\n", outputName); + if ( outputName != NULL ) ImageIO_free( outputName ); + return( -3 ); + case 1 : + switch ( im->sign ) { + default : + fprintf(stderr, "writeGis: such sign not handled in ascii mode for file \'%s\'\n", outputName); + if ( outputName != NULL ) ImageIO_free( outputName ); + return( -3 ); + case SGN_UNSIGNED : + { + unsigned char *theBuf = ( unsigned char * )im->data; + do { + memset( str, 0, _LGTH_STRING_ ); + for ( j=0; jdata; + do { + memset( str, 0, _LGTH_STRING_ ); + for ( j=0; jsign ) */ + break; + case 2 : + switch ( im->sign ) { + default : + fprintf(stderr, "writeGis: such sign not handled in ascii mode for file \'%s\'\n", outputName); + if ( outputName != NULL ) ImageIO_free( outputName ); + return( -3 ); + case SGN_UNSIGNED : + { + unsigned short int *theBuf = ( unsigned short int * )im->data; + do { + memset( str, 0, _LGTH_STRING_ ); + for ( j=0; jdata; + do { + memset( str, 0, _LGTH_STRING_ ); + for ( j=0; jsign ) */ + break; + } /* end of switch ( im->wdim ) */ + } /* end of switch( im->wordKind ) */ + + ImageIO_free( str ); + } + else { + res = _writeInrimageData(im); + } + if ( outputName != NULL ) ImageIO_free( outputName ); + return res; + +} + +CGAL_INLINE_FUNCTION +int testGisHeader(char *,const char *name) { + if (( !strncmp(name+strlen(name)-4, ".dim", 4)) || + ( !strncmp(name+strlen(name)-4, ".ima", 4)) || + ( !strncmp(name+strlen(name)-7, ".ima.gz", 7)) || + ( !strncmp(name+strlen(name)-7, ".dim.gz", 7)) ) + return 0; + else + return -1; +} + + + +CGAL_INLINE_FUNCTION +int readGisHeader( const char* name,_image* im) +{ + char *s, *str = NULL; + int status; + int n=0, nusermax = 20; + + str = (char*)ImageIO_alloc( _LGTH_STRING_+1 ); + + if ( !fgetns(str, _LGTH_STRING_, im) ) + { ImageIO_free( str ); return -1; } + + std::istringstream iss; + iss.str(str); + iss >> im->xdim >> im->ydim >> im->zdim >> im->vdim; + + status = iss.str().length(); + switch ( status ) { + case 2 : im->zdim = 1; + case 3 : im->vdim = 1; + case 4 : break; + default : + fprintf( stderr, "readGisHeader: unable to read dimensions in '%s'\n", name ); + ImageIO_free( str ); + return -1; + } + if ( im->vdim > 1 ) { + im->vectMode = VM_INTERLACED; + } + else { + im->vectMode = VM_SCALAR; + } +#define ADD_USER_STRING { \ + if ( n == 0 ) { \ + im->user = (char**)ImageIO_alloc( nusermax * sizeof( char*) ); \ + for ( n=0; nuser[n] = NULL; \ + n = 0; \ + } \ + im->user[n] = (char*)ImageIO_alloc( 1+strlen( s ) ); \ + strcpy( im->user[n++], s ); \ + } + + + + while( fgetns( str, _LGTH_STRING_, im ) != 0 ) { + s = str; + do { + + while ( *s == ' ' || *s == '\t' ) s++; + + if ( !strncmp( s, "-dx ", 4 ) ) { + s += 4; + status = sscanf( s, "%lf", &(im->vx) ); + if ( status != 1 ) { + fprintf( stderr, "readGisHeader: error while reading -dx in '%s'\n", s-4 ); + *s = '\0'; + } + else { + while ( *s == '.' || (*s >= '0' && *s <= '9') ) s++; + } + } + else if ( !strncmp( s, "-dy ", 4 ) ) { + s += 4; + status = sscanf( s, "%lf", &(im->vy) ); + if ( status != 1 ) { + fprintf( stderr, "readGisHeader: error while reading -dy in '%s'\n", s-4 ); + *s = '\0'; + } + else { + while ( *s == '.' || (*s >= '0' && *s <= '9') ) s++; + } + } + else if ( !strncmp( s, "-dz ", 4 ) ) { + s += 4; + status = sscanf( s, "%lf", &(im->vz) ); + if ( status != 1 ) { + fprintf( stderr, "readGisHeader: error while reading -dz in '%s'\n", s-4 ); + *s = '\0'; + } + else { + while ( *s == '.' || (*s >= '0' && *s <= '9') ) s++; + } + } + else if ( !strncmp( s, "-dt ", 4 ) ) { + ADD_USER_STRING + s += 4; + while ( *s == '.' || (*s >= '0' && *s <= '9') ) s++; + } + + else if ( !strncmp( s, "-type ", 6 ) ) { + s += 6; + if ( !strncmp( s, "U8", 2 ) ) { + im->wdim = 1; + im->wordKind = WK_FIXED; + im->sign = SGN_UNSIGNED; + s += 2; + } + else if ( !strncmp( s, "S8", 2 ) ) { + im->wdim = 1; + im->wordKind = WK_FIXED; + im->sign = SGN_SIGNED; + s += 2; + } + else if ( !strncmp( s, "U16", 3 ) ) { + im->wdim = 2; + im->wordKind = WK_FIXED; + im->sign = SGN_UNSIGNED; + s += 3; + } + else if ( !strncmp( s, "S16", 3 ) ) { + im->wdim = 2; + im->wordKind = WK_FIXED; + im->sign = SGN_SIGNED; + s += 3; + } + else if ( !strncmp( s, "U32", 3 ) ) { + im->wdim = 4; + im->wordKind = WK_FIXED; + im->sign = SGN_UNSIGNED; + s += 3; + } + else if ( !strncmp( s, "S32", 3 ) ) { + im->wdim = 4; + im->wordKind = WK_FIXED; + im->sign = SGN_SIGNED; + s += 3; + } + else if ( !strncmp( s, "FLOAT", 5 ) ) { + im->wdim = sizeof( float ); + im->wordKind = WK_FLOAT; + im->sign = SGN_UNKNOWN; + s += 5; + } + else if ( !strncmp( s, "DOUBLE", 6 ) ) { + im->wdim = sizeof( double ); + im->wordKind = WK_FLOAT; + im->sign = SGN_UNKNOWN; + s += 6; + } + else { + fprintf( stderr, "readGisHeader: unknown type '%s'\n", s-6 ); + *s = '\0'; + } + } + + else if ( !strncmp( s, "-bo ", 4 ) ) { + s += 4; + if ( !strncmp( s, "ABCD", 4 ) ) { + im->endianness = END_BIG; + s += 4; + } + else if ( !strncmp( s, "SUN", 3 ) ) { + im->endianness = END_BIG; + s += 3; + } + else if ( !strncmp( s, "DCBA", 4 ) ) { + im->endianness = END_LITTLE; + s += 4; + } + else if ( !strncmp( s, "ALPHA", 5 ) ) { + im->endianness = END_LITTLE; + s += 5; + } + else { + fprintf( stderr, "readGisHeader: unknown byte order '%s'\n", s-4 ); + *s = '\0'; + } + } + + else if ( !strncmp( s, "-ar ", 4 ) ) { + s += 4; + if ( !strncmp( s, "SUN", 3 ) ) { + im->endianness = END_BIG; + s += 3; + } + else if ( !strncmp( s, "ALPHA", 5 ) ) { + im->endianness = END_LITTLE; + s += 5; + } + else { + fprintf( stderr, "readGisHeader: unknown architecture '%s'\n", s-4 ); + *s = '\0'; + } + } + + else if ( !strncmp( s, "-om ", 4 ) ) { + s += 4; + if ( !strncmp( s, "binar", 5 ) ) { + im->dataMode = DM_BINARY; + s += 5; + } + else if ( !strncmp( s, "ascii", 5 ) ) { + im->dataMode = DM_ASCII; + s += 5; + } + else { + fprintf( stderr, "readGisHeader: unknown data type '%s'\n", s-4 ); + ImageIO_free( str ); + return -1; + } + } + + + else { + fprintf( stderr, "readGisHeader: unknown indentifier '%s'\n", s ); + ADD_USER_STRING + *s = '\0'; + } + + } while( *s != '\0' && *s != '\n' ); + + } + ImageIO_free( str ); + + + if ( im->endianness == END_UNKNOWN ) { + im->endianness = _getEndianness(); + } + + + /* header is read. close header file and open data file. */ + if( name != NULL ) { + + int length = strlen(name) ; + char* data_filename = (char *) ImageIO_alloc(length+4) ; + + if( strcmp( name+length-4, ".dim" ) ) { + fprintf (stderr, + "readGisHeader: error: file header extension must be .dim\n"); + ImageIO_free( data_filename ); + return -1; + } + + ImageIO_close(im); + + + /* open data file + */ + + strcpy(data_filename,name); + strcpy(data_filename+length-3, "ima.gz"); + _openReadImage(im,data_filename); + + if(!im->fd) { + + strcpy(data_filename,name); + strcpy(data_filename+length-3, "ima"); + _openReadImage(im,data_filename); + if(!im->fd) { + fprintf(stderr, "readGisHeader: error: unable to open data file \'%s\'\n", data_filename); + ImageIO_free( data_filename ); + return -1; + + } + } + ImageIO_free( data_filename ); + + + + + + /* read data if ascii + only U8 and S8 + */ + if ( im->dataMode == DM_ASCII ) { + int size = im->xdim * im->ydim * im->zdim * im->vdim * im->wdim; + unsigned int n; + char *tmp; + int ret, iv=0; + + if ( im->wdim != 1 || im->wordKind != WK_FIXED ) { + fprintf(stderr, "readGisHeader: error: unable to read such ascii type\n" ); + return -1; + } + + n = 0 ; + if ( size <= 0 ) return -1; + if(!im->data) { + im->data = ( void*) ImageIO_alloc(size); + if(!im->data) return -1; + } + + n = 0; + str = (char*)ImageIO_alloc( _LGTH_STRING_+1 ); + while( fgetns( str, _LGTH_STRING_, im ) != 0 && + n < im->xdim * im->ydim * im->zdim * im->vdim ) { + tmp = str; + while ( *tmp != '\n' && *tmp != '\0' && *tmp != EOF && + n < im->xdim * im->ydim * im->zdim * im->vdim ) { + /* skip trailing whitespace + */ + while ( *tmp == ' ' || *tmp == '\t' ) + tmp++; + if ( *tmp == '\0' || *tmp == '\n' || *tmp == EOF ) + continue; + + /* read a number + */ + switch ( im->wordKind ) { + case WK_FIXED : + ret = sscanf( tmp, "%d", &iv ); + break; + default : + ImageIO_free( im->data ); im->data = NULL; + ImageIO_free( str ); + return -1; + } + + if ( ret != 1 ) { + fprintf( stderr, "readGisHeader: error in reading ascii data\n" ); + ImageIO_free( im->data ); im->data = NULL; + ImageIO_free( str ); + return -1; + } + + if ( im->wordKind == WK_FIXED + && im->sign == SGN_UNSIGNED + && im->wdim == 1 ) { + unsigned char *buf = (unsigned char *)im->data; + buf += n; + if ( iv < 0 ) *buf = (unsigned char)0; + else if ( iv > 255 ) *buf = (unsigned char)255; + else *buf = (unsigned char)iv; + n ++; + } + else if ( im->wordKind == WK_FIXED + && im->sign == SGN_SIGNED + && im->wdim == 1 ) { + char *buf = (char *)im->data; + buf += n; + if ( iv < -128 ) *buf = (char)-128; + else if ( iv > 127 ) *buf = (char)127; + else *buf = (char)iv; + n ++; + } + else if ( im->wordKind == WK_FIXED + && im->sign == SGN_UNSIGNED + && im->wdim == 2 ) { + unsigned short int *buf = (unsigned short int *)im->data; + buf += n; + if ( iv < 0 ) *buf = (unsigned short int)0; + else if ( iv > 65535 ) *buf = (unsigned short int)65535; + else *buf = (unsigned short int)iv; + n ++; + } + else if ( im->wordKind == WK_FIXED + && im->sign == SGN_SIGNED + && im->wdim == 2 ) { + short int *buf = (short int *)im->data; + buf += n; + if ( iv < -32768 ) *buf = (short int)-32768; + else if ( iv > 32767 ) *buf = (short int)32767; + else *buf = (short int)iv; + n ++; + } + else { + ImageIO_free( im->data ); im->data = NULL; + ImageIO_free( str ); + return -1; + } + + + + /* skip a number + */ + while ( (*tmp >= '0' && *tmp <= '9') || *tmp == '.' || *tmp == '-' ) + tmp++; + } + } + ImageIO_free( str ); + ImageIO_close(im); + } + + } + + + /* check header validity */ + if ( im->xdim > 0 && im->ydim > 0 && im->zdim > 0 && im->vdim > 0 && + im->vx > 0.0 && im->vy > 0.0 && im->vz > 0.0 && + ( im->wordKind == WK_FLOAT || + (im->wordKind == WK_FIXED && im->sign != SGN_UNKNOWN) ) && + im->endianness != END_UNKNOWN ) { + return 0; + } + + return -1; +} + + + +CGAL_INLINE_FUNCTION +int writeGisHeader( const _image* inr ) +{ + const char *proc = "writeGisHeader"; + std::ostringstream oss; + + if ( inr->vectMode == VM_NON_INTERLACED ) { + fprintf( stderr, "%s: can not write non interlaced data\n", proc ); + return -1; + } + + /* dimensions + */ + oss << " " << inr->xdim << " " << inr->ydim; + if ( inr->vdim > 1 ) { + oss << " " << inr->zdim << " " << inr->vdim; + } + else if ( inr->zdim > 1 ) { + oss << " " << inr->zdim; + } + oss << "\n"; + + /* type + */ + oss << "-type "; + switch ( inr->wordKind ) { + case WK_FIXED : + switch( inr->sign ) { + case SGN_UNSIGNED : + oss << "U" << 8*inr->wdim; + break; + case SGN_SIGNED : + oss << "S" << 8*inr->wdim; + break; + default : + fprintf( stderr, "%s: unknown wordSign\n", proc ); + return -1; + } + break; + case WK_FLOAT : + if ( inr->wdim == sizeof( float ) ) { + oss << "FLOAT"; + } + else if ( inr->wdim == sizeof( double ) ) { + oss << "DOUBLE"; + } + else { + fprintf( stderr, "%s: unknown WK_FLOAT word dim\n", proc ); + return -1; + } + break; + default : + fprintf( stderr, "%s: unknown wordKind for image\n", proc ); + return -1; + } + oss << "\n"; + + oss << "-dx "<< inr->vx <<"\n"; + oss << "-dy "<< inr->vy <<"\n"; + if ( inr->zdim > 1 ) + oss << "-dz " << inr->vz << "\n"; + + if ( inr->wdim > 1 ) { + oss << "-bo "; + switch ( _getEndianness() ) { + default : + case END_LITTLE : + oss << "DCBA"; break; + case END_BIG : + oss << "ABCD"; break; + } + oss << "\n"; + } + switch ( inr->dataMode ) { + default : + case DM_BINARY : + oss << "-om binar\n"; + break; + case DM_ASCII : + oss << "-om ascii\n"; + } + if( ImageIO_write( inr, oss.str().data(), oss.str().length()) == 0) { + return -1; + } + return 1; +} + + +CGAL_INLINE_FUNCTION +int writeGisData( const _image*) +{ + return -1; +} diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d8ec962c36..bc3c81d74ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,8 @@ else() endif() add_definitions(-DCGAL_HEADER_ONLY) +message("CGAL WITH HEADER ONLY") +# message("CGAL with libraries") # option for branch build diff --git a/cppfiles.txt b/cppfiles.txt index f0565a27514..5c69f906cf2 100644 --- a/cppfiles.txt +++ b/cppfiles.txt @@ -61,11 +61,11 @@ DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/bmpread DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/recline.cpp" // 1 global variable DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/mincio.cpp" DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/convert.cpp" +DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/recbuffer.cpp" +DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/gif.cpp" // several global variables +DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/gis.cpp" -#include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/recbuffer.cpp" -#include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/gif.cpp" #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/reech4x4.cpp" -#include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/gis.cpp" #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/bmp.cpp" #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/bmpendian.cpp" #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/iris.cpp"