00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifdef _WIN32
00015 #include "../win32/config.h"
00016 #else
00017 #include "../config.h"
00018 #endif
00019
00020 #ifdef __MSDOS__
00021 #include <alloc.h>
00022 #include <sys\stat.h>
00023 #else
00024 #include <sys/types.h>
00025 #include <sys/stat.h>
00026 #ifdef R6000
00027
00028
00029
00030 #include <sys/mode.h>
00031 #endif
00032 #endif
00033
00034 #include <fcntl.h>
00035 #ifdef HAVE_UNISTD_H
00036 #include <unistd.h>
00037 #endif
00038 #ifdef HAVE_STDLIB_H
00039 #include <stdlib.h>
00040 #endif
00041 #include <stdio.h>
00042 #include <string.h>
00043 #include "gif_lib.h"
00044 #include "gif_lib_private.h"
00045
00046
00047
00048
00049 static GifPixelType CodeMask[] = {
00050 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
00051 };
00052
00053 static unsigned char GifVersionPrefix[GIF_STAMP_LEN + 1] = GIF87_STAMP;
00054 static int GifVersionPrefixLen = GIF_STAMP_LEN ;
00055
00056 #define WRITE(_gif,_buf,_len) \
00057 (((GifFilePrivateType*)_gif->Private)->Write ? \
00058 ((GifFilePrivateType*)_gif->Private)->Write(_gif,(unsigned char *)_buf,(int)_len) : \
00059 fwrite(_buf, 1, _len, ((GifFilePrivateType*)_gif->Private)->File))
00060
00061 static int EGifPutWord(int Word, GifFileType *GifFile);
00062 static int EGifSetupCompress(GifFileType *GifFile);
00063 static int EGifCompressLine(GifFileType *GifFile, GifPixelType *Line,
00064 int LineLen);
00065 static int EGifCompressOutput(GifFileType *GifFile, int Code);
00066 static int EGifBufferedOutput(GifFileType *GifFile, GifByteType *Buf, int c);
00067
00068
00069
00070
00071
00072
00073
00074 GifFileType *EGifOpenFileHandle(int FileHandle)
00075 {
00076 GifFileType *GifFile;
00077 GifFilePrivateType *Private;
00078 FILE *f;
00079
00080 if ((GifFile = (GifFileType *) malloc(sizeof(GifFileType))) == NULL) {
00081 _GifError = E_GIF_ERR_NOT_ENOUGH_MEM;
00082 return NULL;
00083 }
00084
00085 memset(GifFile, '\0', sizeof(GifFileType));
00086
00087 if ((Private = (GifFilePrivateType *)
00088 malloc(sizeof(GifFilePrivateType))) == NULL) {
00089 free(GifFile);
00090 _GifError = E_GIF_ERR_NOT_ENOUGH_MEM;
00091 return NULL;
00092 }
00093 if ((Private->HashTable = _InitHashTable()) == NULL) {
00094 free(GifFile);
00095 free(Private);
00096 _GifError = E_GIF_ERR_NOT_ENOUGH_MEM;
00097 return NULL;
00098 }
00099
00100 #ifdef __MSDOS__
00101 setmode(FileHandle, O_BINARY);
00102 #endif
00103
00104 f = fdopen(FileHandle, "wb");
00105
00106 #ifdef __MSDOS__
00107 setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE);
00108 #endif
00109
00110 GifFile->Private = (VoidPtr) Private;
00111 Private->FileHandle = FileHandle;
00112 Private->File = f;
00113 Private->FileState = FILE_STATE_WRITE;
00114
00115 Private->Write = (OutputFunc)0;
00116 GifFile->UserData = (VoidPtr)0;
00117
00118 _GifError = 0;
00119
00120 return GifFile;
00121 }
00122
00123
00124
00125
00126
00127 GifFileType* EGifOpen(void* userData, OutputFunc writeFunc)
00128 {
00129 GifFileType* GifFile;
00130 GifFilePrivateType* Private;
00131
00132 if ((GifFile = (GifFileType *) malloc(sizeof(GifFileType))) == NULL) {
00133 _GifError = E_GIF_ERR_NOT_ENOUGH_MEM;
00134 return NULL;
00135 }
00136
00137 memset(GifFile, '\0', sizeof(GifFileType));
00138
00139 if ((Private = (GifFilePrivateType *)
00140 malloc(sizeof(GifFilePrivateType))) == NULL) {
00141 free(GifFile);
00142 _GifError = E_GIF_ERR_NOT_ENOUGH_MEM;
00143 return NULL;
00144 }
00145
00146 Private->HashTable = _InitHashTable();
00147 if (Private->HashTable == NULL) {
00148 free (GifFile);
00149 free (Private);
00150 _GifError = E_GIF_ERR_NOT_ENOUGH_MEM;
00151 return NULL;
00152 }
00153
00154 GifFile->Private = (VoidPtr) Private;
00155 Private->FileHandle = 0;
00156 Private->File = (FILE *)0;
00157 Private->FileState = FILE_STATE_WRITE;
00158
00159 Private->Write = writeFunc;
00160 GifFile->UserData = userData;
00161
00162 _GifError = 0;
00163
00164 return GifFile;
00165 }
00166
00167
00168
00169
00170
00171
00172 void EGifSetGifVersion(const char *Version)
00173 {
00174 memcpy(GifVersionPrefix + GIF_VERSION_POS, Version, 3);
00175 }
00176
00177
00178
00179
00180
00181 int EGifPutScreenDesc(GifFileType *GifFile,
00182 int Width, int Height, int ColorRes, int BackGround,
00183 const ColorMapObject *ColorMap)
00184 {
00185 int i;
00186 GifByteType Buf[3];
00187 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
00188
00189 if (Private->FileState & FILE_STATE_SCREEN) {
00190
00191 _GifError = E_GIF_ERR_HAS_SCRN_DSCR;
00192 return GIF_ERROR;
00193 }
00194 if (!IS_WRITEABLE(Private)) {
00195
00196 _GifError = E_GIF_ERR_NOT_WRITEABLE;
00197 return GIF_ERROR;
00198 }
00199
00200
00201 #ifndef DEBUG_NO_PREFIX
00202 if (WRITE(GifFile, GifVersionPrefix, GifVersionPrefixLen) !=
00203 GifVersionPrefixLen) {
00204 _GifError = E_GIF_ERR_WRITE_FAILED;
00205 return GIF_ERROR;
00206 }
00207 #endif
00208
00209 GifFile->SWidth = Width;
00210 GifFile->SHeight = Height;
00211 GifFile->SColorResolution = ColorRes;
00212 GifFile->SBackGroundColor = BackGround;
00213 if(ColorMap)
00214 {
00215 GifFile->SColorMap=MakeMapObject(ColorMap->ColorCount,ColorMap->Colors);
00216
00217 if (GifFile->SColorMap == NULL)
00218 {
00219 _GifError = E_GIF_ERR_NOT_ENOUGH_MEM;
00220 return GIF_ERROR;
00221 }
00222 }else
00223 GifFile->SColorMap=NULL;
00224
00225
00226 EGifPutWord(Width, GifFile);
00227 EGifPutWord(Height, GifFile);
00228 if( ColorMap )
00229 Buf[0] = 0x80 | ((ColorRes - 1) << 4) | (ColorMap->BitsPerPixel - 1);
00230 else
00231 Buf[0] = 0x00 | ((ColorRes - 1) << 4) ;
00232 Buf[1] = BackGround;
00233 Buf[2] = 0;
00234 #ifndef DEBUG_NO_PREFIX
00235 WRITE(GifFile, Buf, 3);
00236 #endif
00237
00238
00239 #ifndef DEBUG_NO_PREFIX
00240 if (ColorMap != NULL)
00241 for (i = 0; i < ColorMap->ColorCount; i++) {
00242
00243 Buf[0] = ColorMap->Colors[i].Red;
00244 Buf[1] = ColorMap->Colors[i].Green;
00245 Buf[2] = ColorMap->Colors[i].Blue;
00246 if (WRITE(GifFile, Buf, 3) != 3) {
00247 _GifError = E_GIF_ERR_WRITE_FAILED;
00248 return GIF_ERROR;
00249 }
00250 }
00251 #endif
00252
00253
00254 Private->FileState |= FILE_STATE_SCREEN;
00255
00256 return GIF_OK;
00257 }
00258
00259
00260
00261
00262
00263 int EGifPutImageDesc(GifFileType *GifFile,
00264 int Left, int Top, int Width, int Height, int Interlace,
00265 const ColorMapObject *ColorMap)
00266 {
00267 int i;
00268 GifByteType Buf[3];
00269 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
00270
00271 if (Private->FileState & FILE_STATE_IMAGE &&
00272 #if defined(__MSDOS__) || defined(__GNUC__)
00273 Private->PixelCount > 0xffff0000UL) {
00274 #else
00275 Private->PixelCount > 0xffff0000) {
00276 #endif
00277
00278 _GifError = E_GIF_ERR_HAS_IMAG_DSCR;
00279 return GIF_ERROR;
00280 }
00281 if (!IS_WRITEABLE(Private)) {
00282
00283 _GifError = E_GIF_ERR_NOT_WRITEABLE;
00284 return GIF_ERROR;
00285 }
00286 GifFile->Image.Left = Left;
00287 GifFile->Image.Top = Top;
00288 GifFile->Image.Width = Width;
00289 GifFile->Image.Height = Height;
00290 GifFile->Image.Interlace = Interlace;
00291 if(ColorMap)
00292 {
00293 GifFile->Image.ColorMap =MakeMapObject(ColorMap->ColorCount,ColorMap->Colors);
00294 if (GifFile->Image.ColorMap == NULL)
00295 {
00296 _GifError = E_GIF_ERR_NOT_ENOUGH_MEM;
00297 return GIF_ERROR;
00298 }
00299 }else
00300 GifFile->Image.ColorMap = NULL;
00301
00302
00303 Buf[0] = ',';
00304 #ifndef DEBUG_NO_PREFIX
00305 WRITE(GifFile, Buf, 1);
00306 #endif
00307 EGifPutWord(Left, GifFile);
00308 EGifPutWord(Top, GifFile);
00309 EGifPutWord(Width, GifFile);
00310 EGifPutWord(Height, GifFile);
00311 Buf[0] = (ColorMap ? 0x80 : 0x00) |
00312 (Interlace ? 0x40 : 0x00) |
00313 (ColorMap ? ColorMap->BitsPerPixel - 1 : 0);
00314 #ifndef DEBUG_NO_PREFIX
00315 WRITE(GifFile, Buf, 1);
00316 #endif
00317
00318
00319 #ifndef DEBUG_NO_PREFIX
00320 if (ColorMap != NULL)
00321 for (i = 0; i < ColorMap->ColorCount; i++) {
00322
00323 Buf[0] = ColorMap->Colors[i].Red;
00324 Buf[1] = ColorMap->Colors[i].Green;
00325 Buf[2] = ColorMap->Colors[i].Blue;
00326 if (WRITE(GifFile, Buf, 3) != 3) {
00327 _GifError = E_GIF_ERR_WRITE_FAILED;
00328 return GIF_ERROR;
00329 }
00330 }
00331 #endif
00332 if (GifFile->SColorMap == NULL && GifFile->Image.ColorMap == NULL)
00333 {
00334 _GifError = E_GIF_ERR_NO_COLOR_MAP;
00335 return GIF_ERROR;
00336 }
00337
00338
00339 Private->FileState |= FILE_STATE_IMAGE;
00340 Private->PixelCount = (long) Width * (long) Height;
00341
00342 EGifSetupCompress(GifFile);
00343
00344 return GIF_OK;
00345 }
00346
00347
00348
00349
00350 int EGifPutLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
00351 {
00352 int i;
00353 GifPixelType Mask;
00354 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
00355
00356 if (!IS_WRITEABLE(Private)) {
00357
00358 _GifError = E_GIF_ERR_NOT_WRITEABLE;
00359 return GIF_ERROR;
00360 }
00361
00362 if (!LineLen)
00363 LineLen = GifFile->Image.Width;
00364 if (Private->PixelCount < (unsigned)LineLen) {
00365 _GifError = E_GIF_ERR_DATA_TOO_BIG;
00366 return GIF_ERROR;
00367 }
00368 Private->PixelCount -= LineLen;
00369
00370
00371
00372 Mask = CodeMask[Private->BitsPerPixel];
00373 for (i = 0; i < LineLen; i++) Line[i] &= Mask;
00374
00375 return EGifCompressLine(GifFile, Line, LineLen);
00376 }
00377
00378
00379
00380
00381 int EGifPutComment(GifFileType *GifFile, const char *Comment)
00382 {
00383 unsigned int length = strlen(Comment);
00384 char *buf;
00385
00386 length = strlen(Comment);
00387 if (length <= 255) {
00388 return EGifPutExtension(GifFile, COMMENT_EXT_FUNC_CODE,
00389 length, Comment);
00390 } else {
00391 buf = (char *)Comment;
00392 if (EGifPutExtensionFirst(GifFile, COMMENT_EXT_FUNC_CODE, 255, buf)
00393 == GIF_ERROR) {
00394 return GIF_ERROR;
00395 }
00396 length -= 255;
00397 buf = buf + 255;
00398
00399
00400 while (length > 255) {
00401 if (EGifPutExtensionNext(GifFile, 0, 255, buf) == GIF_ERROR) {
00402 return GIF_ERROR;
00403 }
00404 buf = buf + 255;
00405 length -= 255;
00406 }
00407
00408 if (length > 0) {
00409 if (EGifPutExtensionLast(GifFile, 0, length, buf) == GIF_ERROR) {
00410 return GIF_ERROR;
00411 }
00412 } else {
00413 if (EGifPutExtensionLast(GifFile, 0, 0, NULL) == GIF_ERROR) {
00414 return GIF_ERROR;
00415 }
00416 }
00417 }
00418 return GIF_OK;
00419 }
00420
00421
00422
00423
00424
00425
00426 int EGifPutExtensionFirst(GifFileType *GifFile, int ExtCode, int ExtLen,
00427 const VoidPtr Extension)
00428 {
00429 GifByteType Buf[3];
00430 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
00431
00432 if (!IS_WRITEABLE(Private)) {
00433
00434 _GifError = E_GIF_ERR_NOT_WRITEABLE;
00435 return GIF_ERROR;
00436 }
00437
00438 if (ExtCode == 0)
00439 fwrite(&ExtLen, 1, 1, Private->File);
00440 else
00441 {
00442 Buf[0] = '!';
00443 Buf[1] = ExtCode;
00444 Buf[2] = ExtLen;
00445 fwrite(Buf, 1, 3, Private->File);
00446 }
00447 fwrite(Extension, 1, ExtLen, Private->File);
00448
00449 return GIF_OK;
00450 }
00451
00452
00453
00454
00455 int EGifPutExtensionNext(GifFileType *GifFile, int ExtCode, int ExtLen,
00456 const VoidPtr Extension)
00457 {
00458 GifByteType Buf;
00459 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
00460
00461 if (!IS_WRITEABLE(Private)) {
00462
00463 _GifError = E_GIF_ERR_NOT_WRITEABLE;
00464 return GIF_ERROR;
00465 }
00466
00467 Buf = ExtLen;
00468 fwrite(&Buf, 1, 1, Private->File);
00469 fwrite(Extension, 1, ExtLen, Private->File);
00470
00471 return GIF_OK;
00472 }
00473
00474
00475
00476
00477 int EGifPutExtensionLast(GifFileType *GifFile, int ExtCode, int ExtLen,
00478 const VoidPtr Extension)
00479 {
00480 GifByteType Buf;
00481 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
00482
00483 if (!IS_WRITEABLE(Private)) {
00484
00485 _GifError = E_GIF_ERR_NOT_WRITEABLE;
00486 return GIF_ERROR;
00487 }
00488
00489
00490 if (ExtLen > 0)
00491 {
00492 Buf = ExtLen;
00493 fwrite(&Buf, 1, 1, Private->File);
00494 fwrite(Extension, 1, ExtLen, Private->File);
00495 }
00496
00497 Buf = 0;
00498 fwrite(&Buf, 1, 1, Private->File);
00499
00500 return GIF_OK;
00501 }
00502
00503
00504
00505
00506 int EGifPutExtension(GifFileType *GifFile, int ExtCode, int ExtLen,
00507 const VoidPtr Extension)
00508 {
00509 GifByteType Buf[3];
00510 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
00511
00512 if (!IS_WRITEABLE(Private)) {
00513
00514 _GifError = E_GIF_ERR_NOT_WRITEABLE;
00515 return GIF_ERROR;
00516 }
00517
00518 if (ExtCode == 0)
00519 WRITE(GifFile, (GifByteType*)&ExtLen, 1);
00520 else {
00521 Buf[0] = '!';
00522 Buf[1] = ExtCode;
00523 Buf[2] = ExtLen;
00524 WRITE(GifFile, Buf, 3);
00525 }
00526 WRITE(GifFile, Extension, ExtLen);
00527 Buf[0] = 0;
00528 WRITE(GifFile, Buf, 1);
00529
00530 return GIF_OK;
00531 }
00532
00533
00534
00535
00536 int EGifCloseFile(GifFileType *GifFile)
00537 {
00538 GifByteType Buf;
00539 GifFilePrivateType *Private;
00540 FILE *File;
00541
00542 if (GifFile == NULL) return GIF_ERROR;
00543
00544 Private = (GifFilePrivateType *) GifFile->Private;
00545 if (!IS_WRITEABLE(Private)) {
00546
00547 _GifError = E_GIF_ERR_NOT_WRITEABLE;
00548 return GIF_ERROR;
00549 }
00550
00551 File = Private->File;
00552
00553 Buf = ';';
00554 WRITE(GifFile, &Buf, 1);
00555
00556 if (GifFile->Image.ColorMap) {
00557 FreeMapObject(GifFile->Image.ColorMap);
00558 GifFile->Image.ColorMap = NULL;
00559 }
00560 if (GifFile->SColorMap) {
00561 FreeMapObject(GifFile->SColorMap);
00562 GifFile->SColorMap = NULL;
00563 }
00564 if (Private) {
00565 if (Private->HashTable) {
00566 free((char *) Private->HashTable);
00567 }
00568 free((char *) Private);
00569 }
00570 free(GifFile);
00571
00572 if (File && fclose(File) != 0)
00573 {
00574 _GifError = E_GIF_ERR_CLOSE_FAILED;
00575 return GIF_ERROR;
00576 }
00577 return GIF_OK;
00578 }
00579
00580
00581
00582
00583 static int EGifPutWord(int Word, GifFileType *GifFile)
00584 {
00585 unsigned char c[2];
00586
00587 c[0] = Word & 0xff;
00588 c[1] = (Word >> 8) & 0xff;
00589 #ifndef DEBUG_NO_PREFIX
00590 if (WRITE(GifFile, c, 2) == 2)
00591 return GIF_OK;
00592 else
00593 return GIF_ERROR;
00594 #else
00595 return GIF_OK;
00596 #endif
00597 }
00598
00599
00600
00601
00602 static int EGifSetupCompress(GifFileType *GifFile)
00603 {
00604 int BitsPerPixel;
00605 GifByteType Buf;
00606 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
00607
00608
00609 if (GifFile->Image.ColorMap)
00610 BitsPerPixel = GifFile->Image.ColorMap->BitsPerPixel;
00611 else if (GifFile->SColorMap)
00612 BitsPerPixel = GifFile->SColorMap->BitsPerPixel;
00613 else {
00614 _GifError = E_GIF_ERR_NO_COLOR_MAP;
00615 return GIF_ERROR;
00616 }
00617
00618 Buf = BitsPerPixel = (BitsPerPixel < 2 ? 2 : BitsPerPixel);
00619 WRITE(GifFile, &Buf, 1);
00620
00621 Private->Buf[0] = 0;
00622 Private->BitsPerPixel = BitsPerPixel;
00623 Private->ClearCode = (1 << BitsPerPixel);
00624 Private->EOFCode = Private->ClearCode + 1;
00625 Private->RunningCode = Private->EOFCode + 1;
00626 Private->RunningBits = BitsPerPixel + 1;
00627 Private->MaxCode1 = 1 << Private->RunningBits;
00628 Private->CrntCode = FIRST_CODE;
00629 Private->CrntShiftState = 0;
00630 Private->CrntShiftDWord = 0;
00631
00632
00633 _ClearHashTable(Private->HashTable);
00634
00635
00636 if (EGifCompressOutput(GifFile, Private->ClearCode) == GIF_ERROR)
00637 {
00638 _GifError = E_GIF_ERR_DISK_IS_FULL;
00639 return GIF_ERROR;
00640 }
00641 return GIF_OK;
00642 }
00643
00644
00645
00646
00647
00648
00649
00650 static int EGifCompressLine(GifFileType *GifFile, GifPixelType *Line,
00651 int LineLen)
00652 {
00653 int i = 0, CrntCode, NewCode;
00654 unsigned long NewKey;
00655 GifPixelType Pixel;
00656 GifHashTableType *HashTable;
00657 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
00658
00659 HashTable = Private->HashTable;
00660
00661 if (Private->CrntCode == FIRST_CODE)
00662 CrntCode = Line[i++];
00663 else
00664 CrntCode = Private->CrntCode;
00665
00666 while (i < LineLen) {
00667 Pixel = Line[i++];
00668
00669
00670
00671 NewKey = (((UINT32) CrntCode) << 8) + Pixel;
00672 if ((NewCode = _ExistsHashTable(HashTable, NewKey)) >= 0) {
00673
00674
00675
00676 CrntCode = NewCode;
00677 } else {
00678
00679
00680
00681 if (EGifCompressOutput(GifFile, CrntCode) == GIF_ERROR) {
00682 _GifError = E_GIF_ERR_DISK_IS_FULL;
00683 return GIF_ERROR;
00684 }
00685 CrntCode = Pixel;
00686
00687
00688
00689
00690 if (Private->RunningCode >= LZ_MAX_CODE) {
00691
00692 if (EGifCompressOutput(GifFile, Private->ClearCode)
00693 == GIF_ERROR) {
00694 _GifError = E_GIF_ERR_DISK_IS_FULL;
00695 return GIF_ERROR;
00696 }
00697 Private->RunningCode = Private->EOFCode + 1;
00698 Private->RunningBits = Private->BitsPerPixel + 1;
00699 Private->MaxCode1 = 1 << Private->RunningBits;
00700 _ClearHashTable(HashTable);
00701 } else {
00702
00703 _InsertHashTable(HashTable, NewKey, Private->RunningCode++);
00704 }
00705 }
00706
00707 }
00708
00709
00710 Private->CrntCode = CrntCode;
00711
00712 if (Private->PixelCount == 0) {
00713
00714 if (EGifCompressOutput(GifFile, CrntCode) == GIF_ERROR) {
00715 _GifError = E_GIF_ERR_DISK_IS_FULL;
00716 return GIF_ERROR;
00717 }
00718 if (EGifCompressOutput(GifFile, Private->EOFCode) == GIF_ERROR) {
00719 _GifError = E_GIF_ERR_DISK_IS_FULL;
00720 return GIF_ERROR;
00721 }
00722 if (EGifCompressOutput(GifFile, FLUSH_OUTPUT) == GIF_ERROR) {
00723 _GifError = E_GIF_ERR_DISK_IS_FULL;
00724 return GIF_ERROR;
00725 }
00726 }
00727
00728 return GIF_OK;
00729 }
00730
00731
00732
00733
00734
00735
00736
00737 static int EGifCompressOutput(GifFileType *GifFile, int Code)
00738 {
00739 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
00740 int retval = GIF_OK;
00741
00742 if (Code == FLUSH_OUTPUT) {
00743 while (Private->CrntShiftState > 0) {
00744
00745 if (EGifBufferedOutput(GifFile, Private->Buf,
00746 Private->CrntShiftDWord & 0xff) == GIF_ERROR)
00747 retval = GIF_ERROR;
00748 Private->CrntShiftDWord >>= 8;
00749 Private->CrntShiftState -= 8;
00750 }
00751 Private->CrntShiftState = 0;
00752 if (EGifBufferedOutput(GifFile, Private->Buf,
00753 FLUSH_OUTPUT) == GIF_ERROR)
00754 retval = GIF_ERROR;
00755 } else {
00756 Private->CrntShiftDWord |= ((long) Code) << Private->CrntShiftState;
00757 Private->CrntShiftState += Private->RunningBits;
00758 while (Private->CrntShiftState >= 8) {
00759
00760 if (EGifBufferedOutput(GifFile, Private->Buf,
00761 Private->CrntShiftDWord & 0xff) == GIF_ERROR)
00762 retval = GIF_ERROR;
00763 Private->CrntShiftDWord >>= 8;
00764 Private->CrntShiftState -= 8;
00765 }
00766 }
00767
00768
00769
00770 if (Private->RunningCode >= Private->MaxCode1 && Code <= 4095) {
00771 Private->MaxCode1 = 1 << ++Private->RunningBits;
00772 }
00773
00774 return retval;
00775 }
00776
00777
00778
00779
00780
00781
00782
00783 static int EGifBufferedOutput(GifFileType *GifFile, GifByteType *Buf, int c)
00784 {
00785 if (c == FLUSH_OUTPUT) {
00786
00787 if (Buf[0] != 0 && WRITE(GifFile, Buf, Buf[0]+1) != (unsigned)(Buf[0] + 1))
00788 {
00789 _GifError = E_GIF_ERR_WRITE_FAILED;
00790 return GIF_ERROR;
00791 }
00792
00793 Buf[0] = 0;
00794 if (WRITE(GifFile, Buf, 1) != 1)
00795 {
00796 _GifError = E_GIF_ERR_WRITE_FAILED;
00797 return GIF_ERROR;
00798 }
00799 }
00800 else {
00801 if (Buf[0] == 255) {
00802
00803 if (WRITE(GifFile, Buf, Buf[0] + 1) != (unsigned)(Buf[0] + 1))
00804 {
00805 _GifError = E_GIF_ERR_WRITE_FAILED;
00806 return GIF_ERROR;
00807 }
00808 Buf[0] = 0;
00809 }
00810 Buf[++Buf[0]] = c;
00811 }
00812
00813 return GIF_OK;
00814 }
00815