diff options
| author | Yuval Adam <yuv.adm@gmail.com> | 2014-08-08 14:42:07 +0300 |
|---|---|---|
| committer | Yuval Adam <yuv.adm@gmail.com> | 2014-08-08 14:42:07 +0300 |
| commit | a6163888f3c56123b1db313743c6147ba498732c (patch) | |
| tree | ff7d15d991d1d09ba6cbc0cec80924f57445bfdd /third_party/windows/fltk-1.1.10/src/Fl_GIF_Image.cxx | |
| parent | c3e4c9a25c2910d2d66d52215b3406b13d5b23d5 (diff) | |
Add third_party libs
Diffstat (limited to 'third_party/windows/fltk-1.1.10/src/Fl_GIF_Image.cxx')
| -rw-r--r-- | third_party/windows/fltk-1.1.10/src/Fl_GIF_Image.cxx | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/third_party/windows/fltk-1.1.10/src/Fl_GIF_Image.cxx b/third_party/windows/fltk-1.1.10/src/Fl_GIF_Image.cxx new file mode 100644 index 0000000..21ea9fd --- /dev/null +++ b/third_party/windows/fltk-1.1.10/src/Fl_GIF_Image.cxx @@ -0,0 +1,384 @@ +//
+// "$Id: Fl_GIF_Image.cxx 5845 2007-05-20 00:01:06Z mike $"
+//
+// Fl_GIF_Image routines.
+//
+// Copyright 1997-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// 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 GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+// Contents:
+//
+//
+
+//
+// Include necessary header files...
+//
+
+#include <FL/Fl.H>
+#include <FL/Fl_GIF_Image.H>
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+
+// Read a .gif file and convert it to a "xpm" format (actually my
+// modified one with compressed colormaps).
+
+// Extensively modified from original code for gif2ras by
+// Patrick J. Naughton of Sun Microsystems. The original
+// copyright notice follows:
+
+/* gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image.
+ *
+ * Copyright (c) 1988 by Patrick J. Naughton
+ *
+ * Author: Patrick J. Naughton
+ * naughton@wind.sun.com
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * This file is provided AS IS with no warranties of any kind. The author
+ * shall have no liability with respect to the infringement of copyrights,
+ * trade secrets or any patents by this file or any part thereof. In no
+ * event will the author be liable for any lost revenue or profits or
+ * other special, indirect and consequential damages.
+ *
+ * Comments and additions should be sent to the author:
+ *
+ * Patrick J. Naughton
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Ave, MS 14-40
+ * Mountain View, CA 94043
+ * (415) 336-1080
+ */
+
+typedef unsigned char uchar;
+
+#define NEXTBYTE (uchar)getc(GifFile)
+#define GETSHORT(var) var = NEXTBYTE; var += NEXTBYTE << 8
+
+Fl_GIF_Image::Fl_GIF_Image(const char *infname) : Fl_Pixmap((char *const*)0) {
+ FILE *GifFile; // File to read
+ char **new_data; // Data array
+
+ if ((GifFile = fopen(infname, "rb")) == NULL) {
+ Fl::error("Fl_GIF_Image: Unable to open %s!", infname);
+ return;
+ }
+
+ {char b[6];
+ if (fread(b,1,6,GifFile)<6) {
+ fclose(GifFile);
+ return; /* quit on eof */
+ }
+ if (b[0]!='G' || b[1]!='I' || b[2] != 'F') {
+ fclose(GifFile);
+ Fl::error("Fl_GIF_Image: %s is not a GIF file.\n", infname);
+ return;
+ }
+ if (b[3]!='8' || b[4]>'9' || b[5]!= 'a')
+ Fl::warning("%s is version %c%c%c.",infname,b[3],b[4],b[5]);
+ }
+
+ int Width; GETSHORT(Width);
+ int Height; GETSHORT(Height);
+
+ uchar ch = NEXTBYTE;
+ char HasColormap = ((ch & 0x80) != 0);
+ int BitsPerPixel = (ch & 7) + 1;
+ int ColorMapSize = 1 << BitsPerPixel;
+ // int OriginalResolution = ((ch>>4)&7)+1;
+ // int SortedTable = (ch&8)!=0;
+ ch = NEXTBYTE; // Background Color index
+ ch = NEXTBYTE; // Aspect ratio is N/64
+
+ // Read in global colormap:
+ uchar transparent_pixel = 0;
+ char has_transparent = 0;
+ uchar Red[256], Green[256], Blue[256]; /* color map */
+ if (HasColormap) {
+ for (int i=0; i < ColorMapSize; i++) {
+ Red[i] = NEXTBYTE;
+ Green[i] = NEXTBYTE;
+ Blue[i] = NEXTBYTE;
+ }
+ } else {
+ Fl::warning("%s does not have a colormap.", infname);
+ for (int i = 0; i < ColorMapSize; i++)
+ Red[i] = Green[i] = Blue[i] = (uchar)(255 * i / (ColorMapSize-1));
+ }
+
+ int CodeSize; /* Code size, init from GIF header, increases... */
+ char Interlace;
+
+ for (;;) {
+
+ int i = NEXTBYTE;
+ if (i<0) {
+ fclose(GifFile);
+ Fl::error("Fl_GIF_Image: %s - unexpected EOF",infname);
+ return;
+ }
+ int blocklen;
+
+ // if (i == 0x3B) return 0; eof code
+
+ if (i == 0x21) { // a "gif extension"
+
+ ch = NEXTBYTE;
+ blocklen = NEXTBYTE;
+
+ if (ch==0xF9 && blocklen==4) { // Netscape animation extension
+
+ char bits;
+ bits = NEXTBYTE;
+ getc(GifFile); getc(GifFile); // GETSHORT(delay);
+ transparent_pixel = NEXTBYTE;
+ if (bits & 1) has_transparent = 1;
+ blocklen = NEXTBYTE;
+
+ } else if (ch == 0xFF) { // Netscape repeat count
+ ;
+
+ } else if (ch != 0xFE) { //Gif Comment
+ Fl::warning("%s: unknown gif extension 0x%02x.", infname, ch);
+ }
+ } else if (i == 0x2c) { // an image
+
+ ch = NEXTBYTE; ch = NEXTBYTE; // GETSHORT(x_position);
+ ch = NEXTBYTE; ch = NEXTBYTE; // GETSHORT(y_position);
+ GETSHORT(Width);
+ GETSHORT(Height);
+ ch = NEXTBYTE;
+ Interlace = ((ch & 0x40) != 0);
+ if (ch&0x80) {
+ // read local color map
+ int n = 2<<(ch&7);
+ for (i=0; i < n; i++) {
+ Red[i] = NEXTBYTE;
+ Green[i] = NEXTBYTE;
+ Blue[i] = NEXTBYTE;
+ }
+ }
+ CodeSize = NEXTBYTE+1;
+ break; // okay, this is the image we want
+ } else {
+ Fl::warning("%s: unknown gif code 0x%02x", infname, i);
+ blocklen = 0;
+ }
+
+ // skip the data:
+ while (blocklen>0) {while (blocklen--) {ch = NEXTBYTE;} blocklen=NEXTBYTE;}
+ }
+
+ if (BitsPerPixel >= CodeSize)
+ {
+ // Workaround for broken GIF files...
+ BitsPerPixel = CodeSize - 1;
+ ColorMapSize = 1 << BitsPerPixel;
+ }
+
+ uchar *Image = new uchar[Width*Height];
+
+ int YC = 0, Pass = 0; /* Used to de-interlace the picture */
+ uchar *p = Image;
+ uchar *eol = p+Width;
+
+ int InitCodeSize = CodeSize;
+ int ClearCode = (1 << (CodeSize-1));
+ int EOFCode = ClearCode + 1;
+ int FirstFree = ClearCode + 2;
+ int FinChar = 0;
+ int ReadMask = (1<<CodeSize) - 1;
+ int FreeCode = FirstFree;
+ int OldCode = ClearCode;
+
+ // tables used by LZW decompresser:
+ short int Prefix[4096];
+ uchar Suffix[4096];
+
+ int blocklen = NEXTBYTE;
+ uchar thisbyte = NEXTBYTE; blocklen--;
+ int frombit = 0;
+
+ for (;;) {
+
+/* 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 as a pointer and a bit offset.
+ * In addition, gif adds totally useless and annoying block counts
+ * that must be correctly skipped over. */
+ int CurCode = thisbyte;
+ if (frombit+CodeSize > 7) {
+ if (blocklen <= 0) {
+ blocklen = NEXTBYTE;
+ if (blocklen <= 0) break;
+ }
+ thisbyte = NEXTBYTE; blocklen--;
+ CurCode |= thisbyte<<8;
+ }
+ if (frombit+CodeSize > 15) {
+ if (blocklen <= 0) {
+ blocklen = NEXTBYTE;
+ if (blocklen <= 0) break;
+ }
+ thisbyte = NEXTBYTE; blocklen--;
+ CurCode |= thisbyte<<16;
+ }
+ CurCode = (CurCode>>frombit)&ReadMask;
+ frombit = (frombit+CodeSize)%8;
+
+ if (CurCode == ClearCode) {
+ CodeSize = InitCodeSize;
+ ReadMask = (1<<CodeSize) - 1;
+ FreeCode = FirstFree;
+ OldCode = ClearCode;
+ continue;
+ }
+
+ if (CurCode == EOFCode) break;
+
+ uchar OutCode[1025]; // temporary array for reversing codes
+ uchar *tp = OutCode;
+ int i;
+ if (CurCode < FreeCode) i = CurCode;
+ else if (CurCode == FreeCode) {*tp++ = (uchar)FinChar; i = OldCode;}
+ else {Fl::error("Fl_GIF_Image: %s - LZW Barf!", infname); break;}
+
+ while (i >= ColorMapSize) {*tp++ = Suffix[i]; i = Prefix[i];}
+ *tp++ = FinChar = i;
+ do {
+ *p++ = *--tp;
+ if (p >= eol) {
+ if (!Interlace) YC++;
+ else 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;
+ }
+ if (YC>=Height) YC=0; /* cheap bug fix when excess data */
+ p = Image + YC*Width;
+ eol = p+Width;
+ }
+ } while (tp > OutCode);
+
+ if (OldCode != ClearCode) {
+ Prefix[FreeCode] = (short)OldCode;
+ Suffix[FreeCode] = FinChar;
+ FreeCode++;
+ if (FreeCode > ReadMask) {
+ if (CodeSize < 12) {
+ CodeSize++;
+ ReadMask = (1 << CodeSize) - 1;
+ }
+ else FreeCode--;
+ }
+ }
+ OldCode = CurCode;
+ }
+
+ // We are done reading the file, now convert to xpm:
+
+ // allocate line pointer arrays:
+ w(Width);
+ h(Height);
+ d(1);
+ new_data = new char*[Height+2];
+
+ // transparent pixel must be zero, swap if it isn't:
+ if (has_transparent && transparent_pixel != 0) {
+ // swap transparent pixel with zero
+ p = Image+Width*Height;
+ while (p-- > Image) {
+ if (*p==transparent_pixel) *p = 0;
+ else if (!*p) *p = transparent_pixel;
+ }
+ uchar t;
+ t = Red[0];
+ Red[0] = Red[transparent_pixel];
+ Red[transparent_pixel] = t;
+
+ t = Green[0];
+ Green[0] = Green[transparent_pixel];
+ Green[transparent_pixel] = t;
+
+ t = Blue[0];
+ Blue[0] = Blue[transparent_pixel];
+ Blue[transparent_pixel] = t;
+ }
+
+ // find out what colors are actually used:
+ uchar used[256]; uchar remap[256];
+ int i;
+ for (i = 0; i < ColorMapSize; i++) used[i] = 0;
+ p = Image+Width*Height;
+ while (p-- > Image) used[*p] = 1;
+
+ // remap them to start with printing characters:
+ int base = has_transparent && used[0] ? ' ' : ' '+1;
+ int numcolors = 0;
+ for (i = 0; i < ColorMapSize; i++) if (used[i]) {
+ remap[i] = (uchar)(base++);
+ numcolors++;
+ }
+
+ // write the first line of xpm data (use suffix as temp array):
+ int length = sprintf((char*)(Suffix),
+ "%d %d %d %d",Width,Height,-numcolors,1);
+ new_data[0] = new char[length+1];
+ strcpy(new_data[0], (char*)Suffix);
+
+ // write the colormap
+ new_data[1] = (char*)(p = new uchar[4*numcolors]);
+ for (i = 0; i < ColorMapSize; i++) if (used[i]) {
+ *p++ = remap[i];
+ *p++ = Red[i];
+ *p++ = Green[i];
+ *p++ = Blue[i];
+ }
+
+ // remap the image data:
+ p = Image+Width*Height;
+ while (p-- > Image) *p = remap[*p];
+
+ // split the image data into lines:
+ for (i=0; i<Height; i++) {
+ new_data[i+2] = new char[Width+1];
+ memcpy(new_data[i + 2], (char*)(Image + i*Width), Width);
+ new_data[i + 2][Width] = 0;
+ }
+
+ data((const char **)new_data, Height + 2);
+ alloc_data = 1;
+
+ delete[] Image;
+
+ fclose(GifFile);
+}
+
+
+//
+// End of "$Id: Fl_GIF_Image.cxx 5845 2007-05-20 00:01:06Z mike $".
+//
|
