WP2LaTeX sources.
Revision | 6ba0b40636f799ca2eb852bdc208a47ce86ae1e1 (tree) |
---|---|
Time | 2022-11-16 08:07:30 |
Author | Fojtik |
Commiter | Fojtik |
Create local palette when GIF has multiple scenes.
@@ -28,6 +28,8 @@ | ||
28 | 28 | #include "struct.h" |
29 | 29 | |
30 | 30 | |
31 | +// https://tronche.com/computer-graphics/gif/gif89a.html | |
32 | + | |
31 | 33 | //--------------------------GIF--------------------------- |
32 | 34 | #ifdef SupportGIF |
33 | 35 |
@@ -42,7 +44,7 @@ | ||
42 | 44 | typedef struct |
43 | 45 | { |
44 | 46 | WORD Left, Top, Width, Height; |
45 | - BYTE Flag; | |
47 | + BYTE Flag; //Local Color Table Flag 1 Bit; Interlace Flag 1 Bit; Sort Flag 1 Bit; Reserved 2 Bits; Size of Local Color Table 3 Bits | |
46 | 48 | } TypeGIFImageDescriptor; |
47 | 49 | |
48 | 50 |
@@ -297,7 +299,7 @@ | ||
297 | 299 | } |
298 | 300 | break; |
299 | 301 | |
300 | - case 0x2C: | |
302 | + case 0x2C: | |
301 | 303 | if(LoadGIFImageDescriptor(f,GIFImageDescriptor)!=9) goto FINISH; |
302 | 304 | Interlace = -1; |
303 | 305 | if((GIFImageDescriptor.Flag & 64)>0) Interlace=0; |
@@ -492,17 +494,17 @@ | ||
492 | 494 | if(GlobPalette) NumColors = GlobPalette->Size1D; |
493 | 495 | |
494 | 496 | WORD GlobalColorTableSize; |
495 | - BYTE GlobalColorTableFlag; | |
497 | + //BYTE GlobalColorTableFlag; | |
496 | 498 | if(NumColors>0) |
497 | 499 | { |
498 | 500 | NumColors = 1 << BitsNeeded(NumColors); |
499 | 501 | GlobalColorTableSize = BitsNeeded(NumColors) - 1; |
500 | - GlobalColorTableFlag = 1; | |
502 | + //GlobalColorTableFlag = 1; | |
501 | 503 | } |
502 | 504 | else |
503 | 505 | { |
504 | 506 | GlobalColorTableSize = 0; |
505 | - GlobalColorTableFlag = 0; | |
507 | + //GlobalColorTableFlag = 0; | |
506 | 508 | } |
507 | 509 | |
508 | 510 | BYTE Flag = (Img.Raster->GetPlanes() << 4) | |
@@ -524,7 +526,7 @@ | ||
524 | 526 | else |
525 | 527 | { |
526 | 528 | fwrite(GlobPalette->Data1D,3,GlobPalette->Size1D,f); |
527 | - for(int i=GlobPalette->Size1D; i<GlobalColorTableSize; i++) | |
529 | + for(int i=GlobPalette->Size1D; i<GlobalColorTableSize; i++) // feed rest of palette with zeros. | |
528 | 530 | { |
529 | 531 | fputc(0, f); |
530 | 532 | fputc(0, f); |
@@ -969,6 +971,7 @@ | ||
969 | 971 | TypeGIFImageDescriptor ID; |
970 | 972 | const Image *CurrentImage; |
971 | 973 | APalette *GlobPalette = NULL; |
974 | +bool NeedLocalPalette = false; | |
972 | 975 | |
973 | 976 | if(Img.Raster==NULL) return(-10); |
974 | 977 | if(Img.Raster->GetPlanes()>8) return(-11); |
@@ -980,7 +983,7 @@ | ||
980 | 983 | if(Img.Palette!=NULL) |
981 | 984 | { |
982 | 985 | GlobPalette = Img.Palette; |
983 | - GlobPalette->UsageCount++; | |
986 | + GlobPalette->UsageCount++; | |
984 | 987 | } |
985 | 988 | else |
986 | 989 | { |
@@ -992,6 +995,8 @@ | ||
992 | 995 | } |
993 | 996 | } |
994 | 997 | } |
998 | + else | |
999 | + NeedLocalPalette = true; | |
995 | 1000 | |
996 | 1001 | /* Write GIF signature */ |
997 | 1002 | int ret = StoreGIFHeader(f,Img,GlobPalette); |
@@ -1020,8 +1025,54 @@ | ||
1020 | 1025 | ID.Top = 0; |
1021 | 1026 | ID.Width = CurrentImage->Raster->Size1D; |
1022 | 1027 | ID.Height = CurrentImage->Raster->Size2D; |
1023 | - ID.Flag = 0; | |
1028 | + ID.Flag = 0; | |
1029 | + if(NeedLocalPalette) | |
1030 | + { | |
1031 | + WORD NumColors = 1 << Img.Raster->GetPlanes(); | |
1032 | + GlobPalette = Img.Palette; | |
1033 | + if(GlobPalette!=NULL) | |
1034 | + { | |
1035 | + GlobPalette->UsageCount++; | |
1036 | + } | |
1037 | + else | |
1038 | + { | |
1039 | + GlobPalette = BuildPalette(NumColors, 8); | |
1040 | + if(GlobPalette) | |
1041 | + { | |
1042 | + GlobPalette->UsageCount++; | |
1043 | + FillGray(GlobPalette); | |
1044 | + } | |
1045 | + } | |
1046 | + WORD LocalColorTableSize; | |
1047 | + if(NumColors>0) | |
1048 | + { | |
1049 | + NumColors = 1 << BitsNeeded(NumColors); | |
1050 | + LocalColorTableSize = BitsNeeded(NumColors) - 1; | |
1051 | + } | |
1052 | + else | |
1053 | + LocalColorTableSize = 0; | |
1054 | + if(GlobPalette) | |
1055 | + ID.Flag = 0x80 | (LocalColorTableSize & 0x7); | |
1056 | + } | |
1024 | 1057 | SaveGIFImageDescriptor(f,ID); |
1058 | + if((ID.Flag & 0x80)>0) /*Local Color Map*/ | |
1059 | + { | |
1060 | + WORD LocalColorTableSize = (unsigned)2 << (ID.Flag & 7); | |
1061 | + if(GlobPalette->Size1D >= LocalColorTableSize) | |
1062 | + fwrite(GlobPalette->Data1D,3,LocalColorTableSize,f); | |
1063 | + else | |
1064 | + { | |
1065 | + fwrite(GlobPalette->Data1D,3,GlobPalette->Size1D,f); | |
1066 | + for(int i=GlobPalette->Size1D; i<LocalColorTableSize; i++) // feed rest of palette with zeros. | |
1067 | + { | |
1068 | + fputc(0, f); | |
1069 | + fputc(0, f); | |
1070 | + fputc(0, f); | |
1071 | + } | |
1072 | + } | |
1073 | + if(GlobPalette->UsageCount-- <= 1) delete GlobPalette; | |
1074 | + GlobPalette = NULL; | |
1075 | + } | |
1025 | 1076 | |
1026 | 1077 | WbitStream GIF_Writer(f,CurrentImage->Raster); |
1027 | 1078 | GIF_Writer.codesize = CurrentImage->Raster->GetPlanes(); |
@@ -1031,7 +1082,7 @@ | ||
1031 | 1082 | GIF_Writer.LZW_Compress(); |
1032 | 1083 | |
1033 | 1084 | /* Write terminating 0-byte */ |
1034 | - fputc(0,f); | |
1085 | + fputc(0,f); | |
1035 | 1086 | |
1036 | 1087 | CurrentImage = CurrentImage->Next; |
1037 | 1088 | } while(CurrentImage != NULL); |
@@ -18,7 +18,7 @@ | ||
18 | 18 | #define LineLength 80 /* Split lines after more than LineLength charcters */ |
19 | 19 | |
20 | 20 | #define VersionWP2L "3.pre111" |
21 | -#define VersionDate "12 Nov 2022" /* day (space) month (space) full year */ | |
21 | +#define VersionDate "15 Nov 2022" /* day (space) month (space) full year */ | |
22 | 22 | |
23 | 23 | |
24 | 24 | /* Constants for a flag InputPS */ |