00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "plstdpch.h"
00015
00016 #include "plgifdec.h"
00017 #include "planybmp.h"
00018
00019 extern "C"
00020 {
00021 #define DOEXTERNGIF
00022
00023
00024
00025 #ifdef _WINDOWS
00026 #undef DrawText
00027 #endif
00028 #include "gif_lib.h"
00029 }
00030
00031 #include <stdio.h>
00032
00033 static int
00034 InterlacedOffset[] = { 0, 4, 2, 1 },
00035 InterlacedJumps[] = { 8, 8, 4, 2 };
00036
00038
00040
00041 PLGIFDecoder::PLGIFDecoder()
00042 : PLPicDecoder()
00043 {
00044
00045
00046 }
00047
00048 PLGIFDecoder::~PLGIFDecoder()
00049 {
00050
00051 }
00052
00053 int GIF_Read_Data(GifFileType* pGifFile,GifByteType* pByteType,int length)
00054 {
00055 PLBYTE *ptr;
00056 PLDataSource* pSourceInfo=(PLDataSource*)pGifFile->UserData;
00057
00058 ptr = pSourceInfo->ReadNBytes(length);
00059 memcpy(pByteType,ptr,length);
00060
00061 return length;
00062 }
00063
00064 void PLGIFDecoder::DoDecode(PLBmp *pBmp, PLDataSource *pDataSrc)
00065 {
00066 GifFileType *GifFile;
00067 GifRecordType RecordType;
00068 GifByteType *Extension;
00069 ColorMapObject *ColorMap = NULL;
00070
00071 int CurLine = 0;
00072 int i, Row, Col, Width, Height, Count, j, ExtCode;
00073
00074 GifFile = DGifOpen( (void*)pDataSrc, GIF_Read_Data);
00075
00076 pBmp->Create (GifFile->SWidth, GifFile->SHeight , 8, false);
00077
00078 PLBYTE ** pLineArray = pBmp->GetLineArray();
00079
00080 CurLine = 0;
00081 while (CurLine < GifFile->SHeight)
00082 {
00083 pLineArray[CurLine][0] = GifFile->SBackGroundColor;
00084 CurLine++;
00085 }
00086
00087
00088 do
00089 {
00090 if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
00091 {
00092 PrintGifError();
00093 PLASSERT (false);
00094 }
00095
00096 switch (RecordType)
00097 {
00098 case IMAGE_DESC_RECORD_TYPE:
00099 if (DGifGetImageDesc(GifFile) == GIF_ERROR)
00100 {
00101 PrintGifError();
00102 PLASSERT (false);
00103 }
00104 Row = GifFile->Image.Top;
00105 Col = GifFile->Image.Left;
00106 Width = GifFile->Image.Width;
00107 Height = GifFile->Image.Height;
00108 if (GifFile->Image.Left + GifFile->Image.Width > GifFile->SWidth ||
00109 GifFile->Image.Top + GifFile->Image.Height > GifFile->SHeight)
00110 {
00111 fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n");
00112 PLASSERT (false);
00113 }
00114 if (GifFile->Image.Interlace)
00115 {
00116
00117 for (Count = i = 0; i < 4; i++)
00118 for (j = Row + InterlacedOffset[i]; j < Row + Height;
00119 j += InterlacedJumps[i])
00120 {
00121 GifQprintf("\b\b\b\b%-4d", Count++);
00122 if (DGifGetLine(GifFile, &pLineArray[j][Col], Width) == GIF_ERROR)
00123 {
00124 PrintGifError();
00125 PLASSERT (false);
00126 }
00127 }
00128 }
00129 else
00130 {
00131 for (i = 0; i < Height; i++)
00132 {
00133 GifQprintf("\b\b\b\b%-4d", i);
00134 if (DGifGetLine(GifFile, &pLineArray[Row++][Col], Width) == GIF_ERROR)
00135 {
00136 PrintGifError();
00137 PLASSERT (false);
00138 }
00139 }
00140 }
00141 break;
00142 case EXTENSION_RECORD_TYPE:
00143
00144 if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR)
00145 {
00146 PrintGifError();
00147 PLASSERT (false);
00148 }
00149 while (Extension != NULL)
00150 {
00151 if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR)
00152 {
00153 PrintGifError();
00154 PLASSERT (false);
00155 }
00156 }
00157 break;
00158 case TERMINATE_RECORD_TYPE:
00159 break;
00160 default:
00161 break;
00162 }
00163 } while (RecordType != TERMINATE_RECORD_TYPE);
00164
00165 ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap :
00166 GifFile->SColorMap);
00167
00168 PLBYTE* pb = (PLBYTE*)ColorMap->Colors;
00169 for (i = 0; i < ColorMap->ColorCount; i++)
00170 {
00171 pBmp->SetPaletteEntry(i, pb[0], pb[1], pb[2], 255);
00172 pb += 3;
00173 }
00174
00175 DGifCloseFile(GifFile);
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217