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: */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.