• R/O
  • SSH

wp2latex: Commit

WP2LaTeX sources.


Commit MetaInfo

Revision887f91c36ddaef7635d279f210cc5954c1fb7a54 (tree)
Zeit2022-09-22 04:29:25
AutorFojtik
CommiterFojtik

Log Message

Any attempt to save 2 planes image to BMP caused to create invalid file - expand 4 to 16 colors.

Ändern Zusammenfassung

Diff

diff -r 5e3437a2d8a5 -r 887f91c36dda trunk/sources.cc/images/ras_img.cc
--- a/trunk/sources.cc/images/ras_img.cc Sun Sep 18 23:19:26 2022 +0200
+++ b/trunk/sources.cc/images/ras_img.cc Wed Sep 21 21:29:25 2022 +0200
@@ -868,14 +868,20 @@
868868 if((f=fopen(Name,"wb"))==NULL) return(-1);
869869
870870 StoredPlanes = Img.Raster->GetPlanes();
871- if(Img.ImageType()==ImageGray)
871+ if(StoredPlanes==2) // BMP does not support 2 planes - provide conversion.
872+ {
873+ StoredPlanes = 4;
874+ ConvertMe = new Raster1D_4BitIDX;
875+ ConvertMe->Allocate1D(Img.Raster->GetSize1D());
876+ }
877+ else if(Img.ImageType()==ImageGray)
878+ {
879+ if(StoredPlanes==32) //StoredPlanes==16 ||
872880 {
873- if(StoredPlanes==32) //StoredPlanes==16 ||
874- {
875881 StoredPlanes = 8; //32 bit Gray images needs to be scalled
876882 ConvertMe = CreateRaster1D(Img.Raster->GetSize1D(), StoredPlanes);
877- }
878883 }
884+ }
879885
880886 if(Img.ImageType()==ImageTrueColor)
881887 {
@@ -886,7 +892,7 @@
886892 }
887893 }
888894
889- ldblk=(StoredPlanes*Img.Raster->GetSize1D()+7)/8;
895+ ldblk = (StoredPlanes*Img.Raster->GetSize1D()+7)/8;
890896
891897 memset(&Header,0,sizeof(Header));
892898 memmove(&Header.bfType,"BM",2);
@@ -900,19 +906,19 @@
900906 Header.bfSize = Header.bfOffBits + Img.Raster->Size2D*((ldblk+3) & 0xFFFC);
901907
902908 memset(&Info,0,sizeof(Info));
903- Info.BIH.biSize=40;
904- Info.BIH.biWidth=Img.Raster->GetSize1D();
905- Info.BIH.biHeight=Img.Raster->Size2D;
906- Info.BIH.biPlanes=1;
907- Info.BIH.biBitCount=StoredPlanes;
908- Info.BIH.biCompression=0; //I don't allow compression
909- Info.BIH.biSizeImage=Header.bfSize-Header.bfOffBits;
909+ Info.BIH.biSize = 40;
910+ Info.BIH.biWidth = Img.Raster->GetSize1D();
911+ Info.BIH.biHeight = Img.Raster->Size2D;
912+ Info.BIH.biPlanes = 1;
913+ Info.BIH.biBitCount = StoredPlanes;
914+ Info.BIH.biCompression = 0; //I don't allow compression
915+ Info.BIH.biSizeImage = Header.bfSize-Header.bfOffBits;
910916 if(StoredPlanes==4 || StoredPlanes==8) Info.BIH.biClrUsed=1 << (StoredPlanes);
911917
912918 SaveBmpHeader(f,Header);
913919 SaveBmpInfHdr(f,Info.BIH);
914920
915- if ((StoredPlanes==4)||(StoredPlanes==8))
921+ if((StoredPlanes==4)||(StoredPlanes==8))
916922 { //palette
917923 // gray=p.palette==NULL;
918924 // if(gray) CreatePalette(p.palette,p.planes);
@@ -947,7 +953,7 @@
947953
948954 fseek(f,Header.bfOffBits,SEEK_SET);
949955 k=(-(int)ldblk)& 3;
950- for(i=Img.Raster->Size2D-1;i>=0;i--)
956+ for(i=Img.Raster->Size2D-1; i>=0; i--)
951957 {
952958 if(ConvertMe!=NULL)
953959 {
@@ -2562,15 +2568,19 @@
25622568 {
25632569 char SignatureMain[3];
25642570 char SignatureRelease[3];
2565- WORD Width,Height;
2566- BYTE Flag,BackGround,Nul;
2571+ WORD Width, Height;
2572+ BYTE Flag, BackGround, Aspect;
25672573 } TypeGIFHeader;
2574+
25682575 typedef struct
25692576 {
2570- WORD Left,Top,Width,Height;
2577+ WORD Left, Top, Width, Height;
25712578 BYTE Flag;
25722579 } TypeGIFImageDescriptor;
25732580
2581+
2582+#if SupportART>=4 || SupportART==2
2583+
25742584 inline long LoadGIFHeader(FILE *f,TypeGIFHeader &SU)
25752585 {
25762586 #if defined(__PackedStructures__)
@@ -2578,7 +2588,7 @@
25782588 #else
25792589 return(loadstruct(f,"a3a3wwbbb",
25802590 &SU.SignatureMain,&SU.SignatureRelease,
2581- &SU.Width,&SU.Height,&SU.Flag,&SU.BackGround,&SU.Nul));
2591+ &SU.Width,&SU.Height,&SU.Flag,&SU.BackGround,&SU.Aspect));
25822592 #endif
25832593 }
25842594
@@ -2633,7 +2643,7 @@
26332643 f=file;
26342644 }
26352645
2636-/*This procedure read n bits from the bit stream*/
2646+/** This procedure reads n bits from the bit stream. */
26372647 WORD ABitStream::Read_N(BYTE BitCount)
26382648 {
26392649 static const WORD bmsk[17]={0x0,0x1,0x3,0x7,0xF,0x1F,0x3F,0x7F,0xFF,
@@ -2690,7 +2700,7 @@
26902700 }
26912701
26922702
2693-void Add2Pixel(Raster2DAbstract *Raster,WORD Value,WORD &x,WORD &y,int &Interlace)
2703+void Add2Pixel(Raster2DAbstract *Raster, WORD Value, WORD &x, WORD &y, int &Interlace)
26942704 {
26952705 if(!Raster) return;
26962706 Raster->SetValue2D(x,y,Value);
@@ -2769,12 +2779,12 @@
27692779
27702780 if((GIFHeader.Flag & 0x80)>0) /*Global Color Map*/
27712781 {
2772- X=(unsigned)2 << (GIFHeader.Flag & 7);
2773- Palette=BuildPalette(X,8);
2782+ X = (unsigned)2 << (GIFHeader.Flag & 7);
2783+ Palette = BuildPalette(X,8);
27742784 if(Palette==NULL) goto FINISH;
27752785 if(Palette->Data1D==NULL) goto FINISH;
2776- X*=3;
2777- Nacteno=fread(Palette->Data1D,1,X,f);
2786+ X *= 3;
2787+ Nacteno = fread(Palette->Data1D,1,X,f);
27782788 if(Nacteno<X) goto FINISH;
27792789 }
27802790 /*?-Global Color Map*/
@@ -2951,6 +2961,115 @@
29512961 } //LoadGIF
29522962
29532963 #endif
2964+
2965+
2966+#if SupportGIF>=3
2967+
2968+
2969+/** Calculates number of bits needed to store numbers between 0 and n - 1
2970+ * @param[in] n Number of numbers to store (0 to n - 1)
2971+ * @return Number of bits needed */
2972+static int BitsNeeded(WORD n)
2973+{
2974+int ret = 1;
2975+
2976+ if(!n--)
2977+ return 0;
2978+
2979+ while(n >>= 1)
2980+ ++ret;
2981+
2982+ return ret;
2983+}
2984+
2985+
2986+static int StoreGIFHeader(FILE *f, const Image &Img)
2987+{
2988+/* typedef struct {
2989+ Word LocalScreenWidth, // The width of the image - the first byte is the least significant: "01 00" would be 1 as "00 01" would be 256
2990+ LocalScreenHeight; // The height of the image - the first byte is the least significant again.
2991+ //This byte contains some options in its bits (most to least significant from left to right starting with index 0 - so 0 means 128 and 7 means 1):
2992+ Byte GlobalColorTableSize : 3, // The size of the global color table. The number of colors in the table is calculated with 2^(N+1) - so 001 would stand for 4 colors
2993+ SortFlag : 1, // If set to 1, the global color table is sorted by ascending occurrence in the image data.
2994+ ColorResolution : 3, // The number of bits used to describe a pixel.
2995+ GlobalColorTableFlag : 1; // If set to 1, a global color table is used.
2996+ Byte BackgroundColorIndex; // The index of the background color - irrelevant if no global color table is used
2997+ Byte PixelAspectRatio; // Aspect Ratio - this is ignored nowadays.
2998+} ScreenDescriptor; */
2999+
3000+ if((fwrite("GIF87a", 6, 1, f)) != 1) return -2;
3001+ Wr_word(f,Img.Raster->Size1D);
3002+ Wr_word(f,Img.Raster->Size2D);
3003+
3004+ int NumColors = Img.Raster->GetPlanes();
3005+ BYTE GlobalColorTableSize, GlobalColorTableFlag;
3006+ if(NumColors>0)
3007+ {
3008+ NumColors = 1 << NumColors;
3009+ NumColors = 1 << BitsNeeded(NumColors);
3010+ GlobalColorTableSize = BitsNeeded(NumColors) - 1;
3011+ GlobalColorTableFlag = 1;
3012+ }
3013+ else
3014+ {
3015+ GlobalColorTableSize = 0;
3016+ GlobalColorTableFlag = 0;
3017+ }
3018+
3019+ BYTE Flag = (1<<7) | // If set to 1, a global color table is used.
3020+ (Img.Raster->GetPlanes() << 4) |
3021+ // Sort Flag = 0
3022+ (GlobalColorTableSize & 0x7);
3023+ fputc(Flag, f);
3024+ fputc(0, f);
3025+ fputc(0, f);
3026+return 0;
3027+}
3028+
3029+
3030+inline long SaveGIFImageDescriptor(FILE *f, const TypeGIFImageDescriptor &SU)
3031+{
3032+#if defined(__PackedStructures__)
3033+return(fwrite(&SU,1,sizeof(SU),f));
3034+#else
3035+return(savestruct(f,"wwwwb",
3036+ &SU.Left,&SU.Top,&SU.Width,&SU.Height,&SU.Flag));
3037+#endif
3038+}
3039+
3040+
3041+int SavePictureGIF(const char *Name, const Image &Img)
3042+{
3043+FILE *f;
3044+TypeGIFImageDescriptor ID;
3045+
3046+ if(Img.Raster==NULL) return(-10);
3047+ if(Img.Raster->GetPlanes()>8) return(-11);
3048+
3049+ if((f=fopen(Name,"wb"))==NULL) return(-1);
3050+
3051+ /* Write GIF signature */
3052+ if(StoreGIFHeader(f,Img) < 0)
3053+ {
3054+ fclose(f);
3055+ return -2;
3056+ }
3057+
3058+
3059+
3060+ /* Initiate and write ending image descriptor */
3061+ fputc(';',f);
3062+ memset(&ID, 0, sizeof(ID));
3063+ SaveGIFImageDescriptor(f,ID);
3064+
3065+ fclose(f);
3066+return 0;
3067+}
3068+
3069+#endif
3070+
3071+
3072+#endif
29543073 //-------------------End of GIF routines------------------
29553074
29563075
diff -r 5e3437a2d8a5 -r 887f91c36dda trunk/sources.cc/images/ras_prot.h
--- a/trunk/sources.cc/images/ras_prot.h Sun Sep 18 23:19:26 2022 +0200
+++ b/trunk/sources.cc/images/ras_prot.h Wed Sep 21 21:29:25 2022 +0200
@@ -69,6 +69,12 @@
6969 };
7070
7171
72+class Raster1D_4BitIDX: public Raster1D_4Bit
73+{
74+public: virtual int GetPlanes(void) const {return(-4);};
75+};
76+
77+
7278 /** 8 bit planes */
7379 class Raster1D_8Bit: virtual public Raster1DAbstract
7480 {
Show on old repository browser