GraphicsMagick: coders/wpg.c Requantise properly true color images.
GraphicsMagick Commits <[email protected]>
| Newsgroups | gmane.comp.video.graphicsmagick.cvs |
|---|---|
| Message-ID | <mailman.1925.1673783364.1384.graphicsmagick-commit@lists.sourceforge.net> |
changeset 1beca50cc2b8 in /hg/GraphicsMagick
details: http://hg.GraphicsMagick.org/hg/GraphicsMagick?cmd=changeset;node=1beca50cc2b8
summary: coders/wpg.c Requantise properly true color images.
diffstat:
coders/wpg.c | 3918 +++++++++++++++++++++++++++++----------------------------
1 files changed, 1960 insertions(+), 1958 deletions(-)
diffs (truncated from 3953 to 500 lines):
diff -r 6c85091fcce6 -r 1beca50cc2b8 coders/wpg.c
--- a/coders/wpg.c Sun Jan 15 11:12:20 2023 +0100
+++ b/coders/wpg.c Sun Jan 15 12:48:46 2023 +0100
@@ -1,1795 +1,1795 @@
-/*
-% Copyright (C) 2003-2022 GraphicsMagick Group
-% Copyright (C) 2002 ImageMagick Studio
-%
-% This program is covered by multiple licenses, which are described in
-% Copyright.txt. You should have received a copy of Copyright.txt with this
-% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
-%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% W W PPPP GGGG %
-% W W P P G %
-% W W W PPPP G GGG %
-% WW WW P G G %
-% W W P GGG %
-% %
-% %
-% Read WordPerfect Image Format. %
-% %
-% %
-% Software Design %
-% Jaroslav Fojtik %
-% June 2000 - 2023 %
-% Rework for GraphicsMagick %
-% Bob Friesenhahn %
-% Feb-May 2003 %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%
-*/
-
-/*
- Include declarations.
-*/
-#include "magick/studio.h"
-#include "magick/blob.h"
-#include "magick/colormap.h"
-#include "magick/constitute.h"
-#include "magick/log.h"
-#include "magick/magic.h"
-#include "magick/magick.h"
-#include "magick/pixel_cache.h"
-#include "magick/shear.h"
-#include "magick/tempfile.h"
-#include "magick/transform.h"
-#include "magick/quantize.h"
-#include "magick/utility.h"
-
-
-typedef struct
- {
- unsigned char Red;
- unsigned char Blue;
- unsigned char Green;
- } RGB_Record;
-
-/* Default palette for WPG level 1 */
-static const RGB_Record WPG1_Palette[256]={
-{ 0, 0, 0}, { 0, 0,168},
-{ 0,168, 0}, { 0,168,168},
-{168, 0, 0}, {168, 0,168},
-{168, 84, 0}, {168,168,168},
-{ 84, 84, 84}, { 84, 84,252},
-{ 84,252, 84}, { 84,252,252},
-{252, 84, 84}, {252, 84,252},
-{252,252, 84}, {252,252,252}, /*16*/
-{ 0, 0, 0}, { 20, 20, 20},
-{ 32, 32, 32}, { 44, 44, 44},
-{ 56, 56, 56}, { 68, 68, 68},
-{ 80, 80, 80}, { 96, 96, 96},
-{112,112,112}, {128,128,128},
-{144,144,144}, {160,160,160},
-{180,180,180}, {200,200,200},
-{224,224,224}, {252,252,252}, /*32*/
-{ 0, 0,252}, { 64, 0,252},
-{124, 0,252}, {188, 0,252},
-{252, 0,252}, {252, 0,188},
-{252, 0,124}, {252, 0, 64},
-{252, 0, 0}, {252, 64, 0},
-{252,124, 0}, {252,188, 0},
-{252,252, 0}, {188,252, 0},
-{124,252, 0}, { 64,252, 0}, /*48*/
-{ 0,252, 0}, { 0,252, 64},
-{ 0,252,124}, { 0,252,188},
-{ 0,252,252}, { 0,188,252},
-{ 0,124,252}, { 0, 64,252},
-{124,124,252}, {156,124,252},
-{188,124,252}, {220,124,252},
-{252,124,252}, {252,124,220},
-{252,124,188}, {252,124,156}, /*64*/
-{252,124,124}, {252,156,124},
-{252,188,124}, {252,220,124},
-{252,252,124}, {220,252,124},
-{188,252,124}, {156,252,124},
-{124,252,124}, {124,252,156},
-{124,252,188}, {124,252,220},
-{124,252,252}, {124,220,252},
-{124,188,252}, {124,156,252}, /*80*/
-{180,180,252}, {196,180,252},
-{216,180,252}, {232,180,252},
-{252,180,252}, {252,180,232},
-{252,180,216}, {252,180,196},
-{252,180,180}, {252,196,180},
-{252,216,180}, {252,232,180},
-{252,252,180}, {232,252,180},
-{216,252,180}, {196,252,180}, /*96*/
-{180,220,180}, {180,252,196},
-{180,252,216}, {180,252,232},
-{180,252,252}, {180,232,252},
-{180,216,252}, {180,196,252},
-{0,0,112}, {28,0,112},
-{56,0,112}, {84,0,112},
-{112,0,112}, {112,0,84},
-{112,0,56}, {112,0,28}, /*112*/
-{112,0,0}, {112,28,0},
-{112,56,0}, {112,84,0},
-{112,112,0}, {84,112,0},
-{56,112,0}, {28,112,0},
-{0,112,0}, {0,112,28},
-{0,112,56}, {0,112,84},
-{0,112,112}, {0,84,112},
-{0,56,112}, {0,28,112}, /*128*/
-{56,56,112}, {68,56,112},
-{84,56,112}, {96,56,112},
-{112,56,112}, {112,56,96},
-{112,56,84}, {112,56,68},
-{112,56,56}, {112,68,56},
-{112,84,56}, {112,96,56},
-{112,112,56}, {96,112,56},
-{84,112,56}, {68,112,56}, /*144*/
-{56,112,56}, {56,112,69},
-{56,112,84}, {56,112,96},
-{56,112,112}, {56,96,112},
-{56,84,112}, {56,68,112},
-{80,80,112}, {88,80,112},
-{96,80,112}, {104,80,112},
-{112,80,112}, {112,80,104},
-{112,80,96}, {112,80,88}, /*160*/
-{112,80,80}, {112,88,80},
-{112,96,80}, {112,104,80},
-{112,112,80}, {104,112,80},
-{96,112,80}, {88,112,80},
-{80,112,80}, {80,112,88},
-{80,112,96}, {80,112,104},
-{80,112,112}, {80,114,112},
-{80,96,112}, {80,88,112}, /*176*/
-{0,0,64}, {16,0,64},
-{32,0,64}, {48,0,64},
-{64,0,64}, {64,0,48},
-{64,0,32}, {64,0,16},
-{64,0,0}, {64,16,0},
-{64,32,0}, {64,48,0},
-{64,64,0}, {48,64,0},
-{32,64,0}, {16,64,0}, /*192*/
-{0,64,0}, {0,64,16},
-{0,64,32}, {0,64,48},
-{0,64,64}, {0,48,64},
-{0,32,64}, {0,16,64},
-{32,32,64}, {40,32,64},
-{48,32,64}, {56,32,64},
-{64,32,64}, {64,32,56},
-{64,32,48}, {64,32,40}, /*208*/
-{64,32,32}, {64,40,32},
-{64,48,32}, {64,56,32},
-{64,64,32}, {56,64,32},
-{48,64,32}, {40,64,32},
-{32,64,32}, {32,64,40},
-{32,64,48}, {32,64,56},
-{32,64,64}, {32,56,64},
-{32,48,64}, {32,40,64}, /*224*/
-{44,44,64}, {48,44,64},
-{52,44,64}, {60,44,64},
-{64,44,64}, {64,44,60},
-{64,44,52}, {64,44,48},
-{64,44,44}, {64,48,44},
-{64,52,44}, {64,60,44},
-{64,64,44}, {60,64,44},
-{52,64,44}, {48,64,44}, /*240*/
-{44,64,44}, {44,64,48},
-{44,64,52}, {44,64,60},
-{44,64,64}, {44,60,64},
-{44,55,64}, {44,48,64},
-{0,0,0}, {0,0,0},
-{0,0,0}, {0,0,0},
-{0,0,0}, {0,0,0},
-{0,0,0}, {0,0,0} /*256*/
-};
-
-
-static int ApproveFormatForWPG(const char *Format)
-{
- if(!strcmp(Format,"PFB")) return 0;
- return 1;
-}
-
-
-
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
-% I s W P G %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% IsWPG() returns True if the image format type, identified by the magick
-% string, is WPG.
-%
-% The format of the IsWPG method is:
-%
-% unsigned int IsWPG(const unsigned char *magick,const size_t length)
-%
-% A description of each parameter follows:
-%
-% o status: Method IsWPG returns True if the image format type is WPG.
-%
-% o magick: This string is generally the first few bytes of an image file
-% or blob.
-%
-% o length: Specifies the length of the magick string.
-%
-%
-*/
-static unsigned int IsWPG(const unsigned char *magick,const size_t length)
-{
- if (length < 4)
- return(False);
- if (memcmp(magick,"\377WPC",4) == 0)
- return(True);
- return(False);
-}
-
-static int Rd_WP_DWORD(Image *image, unsigned long *d)
-{
- unsigned char b;
-
- b = ReadBlobByte(image);
- *d = b;
- if (b < 0xFFU)
- return 1;
- b = ReadBlobByte(image);
- *d = (unsigned long) b;
- b = ReadBlobByte(image);
- *d+=(unsigned long) b*256l;
- if (*d < 0x8000)
- return 3;
- *d=(*d & 0x7FFF) << 16;
- b = ReadBlobByte(image);
- *d += (unsigned long) b;
- b=ReadBlobByte(image);
- *d += (unsigned long) b*256l;
- return 5;
-}
-
-
-static MagickPassFail InsertRow(unsigned char *p,unsigned long y, Image *image, int bpp)
-{
- unsigned long
- x;
- register PixelPacket
- *q;
- MagickPassFail RetVal = MagickFail;
- IndexPacket index;
- IndexPacket *indexes;
-
- if (image->logging)
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),
- "Insert row %ld of %lu...", y, image->rows);
-
- q = SetImagePixels(image,0,y,image->columns,1);
- if(q == (PixelPacket *) NULL)
- return MagickFail;
-
- switch (bpp)
- {
- case 1: /* Convert bitmap scanline. WP seems to ignore palette even if it is present. */
- RetVal = ImportImagePixelArea(image,GrayQuantum,bpp,p,NULL,0);
- break;
-
- case 4: /* Convert PseudoColor scanline. */
- case 8: /* Convert PseudoColor scanline. */
- RetVal = ImportImagePixelArea(image,IndexQuantum,bpp,p,NULL,0);
- break;
-
- case 2: /* Convert PseudoColor scanline. */
- {
- indexes=AccessMutableIndexes(image);
- if ((image->storage_class != PseudoClass) ||
- (indexes == (IndexPacket *) NULL))
- {
- if (image->logging)
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),
- "Image has no colormap, skipping...");
- return MagickFail;
- }
- x = 0;
- while(x+3 < image->columns)
- {
- index = (IndexPacket)((*p >> 6) & 0x3);
- VerifyColormapIndex(image,index);
- indexes[x++]=index;
- *q++=image->colormap[index];
- index = (IndexPacket)((*p >> 4) & 0x3);
- VerifyColormapIndex(image,index);
- indexes[x++]=index;
- *q++=image->colormap[index];
- index = (IndexPacket)((*p >> 2) & 0x3);
- VerifyColormapIndex(image,index);
- indexes[x++]=index;
- *q++ = image->colormap[index];
- index = (IndexPacket)((*p) & 0x3);
- VerifyColormapIndex(image,index);
- indexes[x++]=index;
- *q++ = image->colormap[index];
- p++;
- }
- if(x < image->columns)
- {
- index = (IndexPacket) ((*p >> 6) & 0x3);
- VerifyColormapIndex(image,index);
- indexes[x++] = index;
- *q++=image->colormap[index];
- if(x < image->columns)
- {
- index = (IndexPacket) ((*p >> 4) & 0x3);
- VerifyColormapIndex(image,index);
- indexes[x++] = index;
- *q++=image->colormap[index];
- if(x < image->columns)
- {
- index = (IndexPacket)((*p >> 2) & 0x3);
- VerifyColormapIndex(image,index);
- indexes[x] = index;
- *q++=image->colormap[index];
- }
- }
- /* p++; */
- }
- RetVal = MagickPass;
- break;
- }
-
- case 24: /* Convert DirectColor scanline. */
- RetVal = ImportImagePixelArea(image,RGBQuantum,8,p,NULL,0);
- break;
-
- default:
- if (image->logging)
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),
- "Unsupported bits per pixel %u",bpp);
-
- return MagickFail; /* emit some error here */
- }
-
-
- if(RetVal==MagickFail)
- {
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),"ImportImagePixelArea failed for row: %lu, bpp: %d", y, bpp);
- return MagickFail;
- }
-
- if(!SyncImagePixels(image))
- {
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),"SyncImagePixels failed for row: %ld, bpp: %d", y, bpp);
- return MagickFail;
- }
-
-return RetVal;
-}
-
-
-/* Helper for WPG1 raster reader. */
-#define InsertByte(b) \
-{ \
- BImgBuff[x]=b; \
- x++; \
- if((long) x>=ldblk) \
- { \
- if(InsertRow(BImgBuff,y,image,bpp)==MagickFail) { RetVal=-6; goto unpack_wpg_raser_error; } \
- x=0; \
- y++; \
- if(y>=image->rows) break; \
- } \
-}
-
-
-/** Call this function to ensure that all data matrix is filled with something. This function
- * is used only to error recovery. */
-static MagickPassFail ZeroFillMissingData(unsigned char *BImgBuff,unsigned long x, unsigned long y, Image *image,
- int bpp, long ldblk)
-{
- MagickPassFail
- status = MagickPass;
-
- while(y<image->rows && image->exception.severity!=UndefinedException)
- {
- if((long) x<ldblk)
- {
- memset(BImgBuff+x, 0, (size_t)ldblk-(size_t)x);
- if(x == 0)
- x = ldblk; /* Do not memset any more */
- else
- x = 0; /* Next pass will need to clear whole row */
- }
- if(InsertRow(BImgBuff,y,image,bpp) == MagickFail)
- {
- status = MagickFail;
- break;
- }
- y++;
- }
- return status;
-}
-
-
-/* WPG1 raster reader.
- * @return 0 - OK; -2 - alocation failure; -3 unaligned column; -4 - image row overflowl
- -5 - blob read error; -6 - row insert problem */
-static int UnpackWPGRaster(Image *image,int bpp)
-{
- unsigned long
- x,
- y;
-
- int
- i;
- int RetVal = 0;
-
- unsigned char
- bbuf,
- *BImgBuff,
- RunCount;
-
- long
- ldblk;
-
- x=0;
- y=0;
-
- ldblk = (long)((bpp*image->columns+7)/8);
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),
- "Raster allocation size: %ld byte%s",
- ldblk, (ldblk > 1 ? "s" : ""));
- BImgBuff=MagickAllocateResourceLimitedMemory(unsigned char *,(size_t) ldblk);
- if(BImgBuff==NULL) return(-2);
- (void) memset(BImgBuff,0,(size_t) ldblk);
-
- while(y<image->rows)
- {
- i = ReadBlobByte(image);
- if(i==EOF)
- {
- ZeroFillMissingData(BImgBuff,x,y,image,bpp,ldblk);
- MagickFreeResourceLimitedMemory(BImgBuff);
- return(-5);
- }
- bbuf = i;
-
- RunCount=bbuf & 0x7F;
- if(bbuf & 0x80)
- {
- if(RunCount) /* repeat next byte runcount * */
- {
- bbuf=ReadBlobByte(image);
- for(i=0;i<(int) RunCount;i++) InsertByte(bbuf);
- }
- else { /* read next byte as RunCount; repeat 0xFF runcount* */
- RunCount=ReadBlobByte(image);
- for(i=0;i<(int) RunCount;i++) InsertByte(0xFF);
- }
- }
- else {
- if(RunCount) /* next runcount byte are readed directly */
- {
- for(i=0;i < (int) RunCount;i++)
- {
- bbuf=ReadBlobByte(image);
- InsertByte(bbuf);
- }
- }
- else { /* repeat previous line runcount* */
- i = ReadBlobByte(image);
- if(i==EOF)
- {
- ZeroFillMissingData(BImgBuff,x,y,image,bpp,ldblk);
- MagickFreeResourceLimitedMemory(BImgBuff);
- return -7;
- }
- RunCount = i;
- if(x!=0) { /* attempt to duplicate row from x position: */