This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository legacy-imlib2.

View the commit online.

commit 27db42330ee33bed7dfee1ebeb89a067e7ef4252
Author: q3cpma <q3c...@posteo.net>
AuthorDate: Wed Jan 11 19:32:11 2023 +0100

    PNM loader: add read support for PAM
---
 src/modules/loaders/loader_pnm.c | 508 +++++++++++++++++++++++++++++----------
 1 file changed, 380 insertions(+), 128 deletions(-)

diff --git a/src/modules/loaders/loader_pnm.c b/src/modules/loaders/loader_pnm.c
index b6f06b6..2f20688 100644
--- a/src/modules/loaders/loader_pnm.c
+++ b/src/modules/loaders/loader_pnm.c
@@ -3,11 +3,17 @@
 
 #include <ctype.h>
 #include <stdbool.h>
+#include <string.h>
 
 #define DBG_PFX "LDR-pnm"
 
 static const char  *const _formats[] = { "pnm", "ppm", "pgm", "pbm", "pam" };
 
+typedef enum
+   { BW_RAW_PACKED, BW_RAW, BW_PLAIN, GRAY_RAW, GRAY_PLAIN, RGB_RAW, RGB_PLAIN,
+   XV332
+} px_type;
+
 static struct {
    const unsigned char *data, *dptr;
    unsigned int        size;
@@ -78,6 +84,7 @@ mm_getu(unsigned int *pui)
    bool                comment;
 
    /* Strip whitespace and comments */
+
    for (comment = false;;)
      {
         ch = mm_getc();
@@ -114,70 +121,202 @@ mm_getu(unsigned int *pui)
    return 0;                    /* Ok */
 }
 
+static int
+mm_parse_pam_header(unsigned *w, unsigned *h, unsigned *v, px_type * pxt,
+                    char *alpha)
+{
+   char                tuple_type[32] = { 0 };
+   unsigned            tti = 0, d;
+
+   for (int ch;;)
+     {
+        if ((ch = mm_getc()) == -1)
+           return -1;
+        if (ch == '#')
+          {
+             do
+               {
+                  if ((ch = mm_getc()) == -1)
+                     return -1;
+               }
+             while (ch != '\n');
+          }
+        else
+          {
+             char                key[9] = { 0 };        /* max key size per spec: 8 */
+             for (unsigned ki = 0; !isspace(ch) && ki < sizeof(key) - 1; ++ki)
+               {
+                  key[ki] = (char)ch;
+                  if ((ch = mm_getc()) == -1)
+                     return -1;
+               }
+             if (!strcmp(key, "ENDHDR"))
+                break;
+
+             unsigned int       *p = NULL;
+
+             if (!strcmp(key, "HEIGHT"))
+                p = h;
+             else if (!strcmp(key, "WIDTH"))
+                p = w;
+             else if (!strcmp(key, "DEPTH"))
+                p = &d;
+             else if (!strcmp(key, "MAXVAL"))
+                p = v;
+             else if (!strcmp(key, "TUPLTYPE"))
+               {
+                  while (isspace(ch))
+                    {
+                       if ((ch = mm_getc()) == -1)
+                          return -1;
+                    }
+                  if (tti != 0) /* not the first TUPLE_TYPE header */
+                    {
+                       if (tti < sizeof(tuple_type) - 1)
+                          tuple_type[tti++] = ' ';
+                    }
+                  while (ch != '\n' && tti < sizeof(tuple_type) - 1)
+                    {
+                       tuple_type[tti++] = ch;
+                       if ((ch = mm_getc()) == -1)
+                          return -1;
+                    }
+               }
+             else               /* unknown header */
+               {
+
+               }
+
+             if (p)
+               {
+                  if (mm_getu(p) == -1)
+                     return -1;
+               }
+          }
+     }
+
+   *alpha = (tti >= 6 && !strcmp(tuple_type + tti - 6, "_ALPHA"));
+
+   if (!strncmp(tuple_type, "BLACKANDWHITE", 13))
+     {
+        *pxt = BW_RAW;
+        /* assert(d == *alpha + 1);
+         * assert(*v == 1); */
+     }
+   else if (!strncmp(tuple_type, "GRAYSCALE", 9))
+     {
+        *pxt = GRAY_RAW;
+        /* assert(d == *alpha + 1); */
+     }
+   else if (!strncmp(tuple_type, "RGB", 3))
+     {
+        *pxt = RGB_RAW;
+        /* assert(d == *alpha + 3); */
+     }
+   else                         /* unknown tuple type */
+     {
+        return -1;
+     }
+   return 0;
+}
+
 static int
 _load(ImlibImage * im, int load_data)
 {
    int                 rc;
-   int                 c, p;
-   int                 w, h, v, numbers, count;
+   int                 p;
+   unsigned int        w, h, v, hlen;
    uint8_t            *data = ""     /* for the binary versions */
    uint8_t            *ptr = NULL;
    int                *idata = NULL;    /* for the ASCII versions */
    uint32_t           *ptr2, rval, gval, bval;
-   int                 i, j, x, y;
+   unsigned            i, j, x, y;
+   px_type             pxt;
 
    rc = LOAD_FAIL;
 
    mm_init(im->fi->fdata, im->fi->fsize);
 
    /* read the header info */
-
-   c = mm_getc();
-   if (c != 'P')
+   if (mm_getc() != 'P')
       goto quit;
 
-   numbers = 3;
    p = mm_getc();
-   if (p == '1' || p == '4')
-      numbers = 2;              /* bitimages don't have max value */
-
-   if ((p < '1') || (p > '8'))
-      goto quit;
-
-   /* read numbers */
-   w = h = 0;
-   v = 255;
-   for (count = i = 0; count < numbers; i++)
+   hlen = 3;
+   switch (p)
      {
-        if (mm_getu(&gval))
-           goto quit;
-
-        if (p == '7' && i == 0)
+     case '1':
+        pxt = BW_PLAIN;
+        hlen = 2;
+        break;
+     case '2':
+        pxt = GRAY_PLAIN;
+        break;
+     case '3':
+        pxt = RGB_PLAIN;
+        break;
+     case '4':
+        pxt = BW_RAW_PACKED;
+        hlen = 2;
+        break;
+     case '5':
+        pxt = GRAY_RAW;
+        break;
+     case '6':
+        pxt = RGB_RAW;
+        break;
+     case '7':
+        if (mm_getc() != '\n')
+          {
+             if (mm_getu(&gval) || gval != 332) /* XV thumbnail format */
+                goto quit;
+             pxt = XV332;
+          }
+        else
           {
-             if (gval != 332)
+             if (mm_parse_pam_header(&w, &h, &v, &pxt, &im->has_alpha))
                 goto quit;
-             else
-                continue;
+             hlen = 0;
           }
+        break;
+     case '8':                 /* not in netpbm, unknown format provenance (Imlib2 specific?) */
+        pxt = RGB_RAW;
+        im->has_alpha = 1;
+        break;
+     default:
+        goto quit;
+     }
 
-        count++;
-        switch (count)
+   /* read header for non-PAM formats */
+   if (hlen != 0)
+     {
+        w = h = 0;
+        v = 255;
+        for (i = 0; i < hlen; i++)
           {
-          case 1:              /* width */
-             w = gval;
-             break;
-          case 2:              /* height */
-             h = gval;
-             break;
-          case 3:              /* max value, only for color and greyscale */
-             v = gval;
-             break;
+             if (mm_getu(&gval))
+                goto quit;
+
+             switch (i)
+               {
+               case 0:         /* width */
+                  w = gval;
+                  break;
+               case 1:         /* height */
+                  h = gval;
+                  break;
+               case 2:         /* max value, only for color and greyscale */
+                  v = gval;
+                  break;
+               }
           }
      }
-   if ((v < 0) || (v > 255))
+
+   if (v > 255)
       goto quit;
 
-   D("P%c: WxH=%dx%d V=%d\n", p, w, h, v);
+   D("P%c: pxtype=%d WxH=%ux%u V=%u A=%s\n",
+     p, pxt, w, h, v, im->has_alpha ? "YES" : "NO");
 
    rc = LOAD_BADIMAGE;          /* Format accepted */
 
@@ -186,8 +325,6 @@ _load(ImlibImage * im, int load_data)
    if (!IMAGE_DIMENSIONS_OK(w, h))
       goto quit;
 
-   im->has_alpha = p == '8';
-
    if (!load_data)
       QUIT_WITH_RC(LOAD_SUCCESS);
 
@@ -198,25 +335,27 @@ _load(ImlibImage * im, int load_data)
       QUIT_WITH_RC(LOAD_OOM);
 
    /* start reading the data */
-   switch (p)
+   switch (pxt)
      {
-     case '1':                 /* ASCII monochrome */
+     case BW_PLAIN:            /* ASCII monochrome */
         for (y = 0; y < h; y++)
           {
              for (x = 0; x < w; x++)
                {
-                  i = mm_get01();
-                  if (i < 0)
+                  int                 px = mm_get01();
+
+                  if (px < 0)
                      goto quit;
 
-                  *ptr2++ = i ? 0xff000000 : 0xffffffff;
+                  *ptr2++ = px ? 0xff000000 : 0xffffffff;
                }
 
              if (im->lc && __imlib_LoadProgressRows(im, y, 1))
                 goto quit_progress;
           }
         break;
-     case '2':                 /* ASCII greyscale */
+
+     case GRAY_PLAIN:          /* ASCII greyscale */
         for (y = 0; y < h; y++)
           {
              for (x = 0; x < w; x++)
@@ -231,7 +370,8 @@ _load(ImlibImage * im, int load_data)
                   else
                     {
                        *ptr2++ =
-                          0xff000000 | (((gval * 255) / v) << 16) |
+                          0xff000000 |
+                          (((gval * 255) / v) << 16) |
                           (((gval * 255) / v) << 8) | ((gval * 255) / v);
                     }
                }
@@ -240,7 +380,8 @@ _load(ImlibImage * im, int load_data)
                 goto quit_progress;
           }
         break;
-     case '3':                 /* ASCII RGB */
+
+     case RGB_PLAIN:           /* ASCII RGB */
         for (y = 0; y < h; y++)
           {
              for (x = 0; x < w; x++)
@@ -269,7 +410,8 @@ _load(ImlibImage * im, int load_data)
                 goto quit_progress;
           }
         break;
-     case '4':                 /* binary 1bit monochrome */
+
+     case BW_RAW_PACKED:       /* binary 1bit monochrome */
         data = "" + 7) / 8 * sizeof(uint8_t));
         if (!data)
            QUIT_WITH_RC(LOAD_OOM);
@@ -299,36 +441,49 @@ _load(ImlibImage * im, int load_data)
                 goto quit_progress;
           }
         break;
-     case '5':                 /* binary 8bit grayscale GGGGGGGG */
-        data = "" * sizeof(uint8_t) * w);
-        if (!data)
-           QUIT_WITH_RC(LOAD_OOM);
 
-        ptr2 = im->data;
-        for (y = 0; y < h; y++)
+     case BW_RAW:              /* binary 1byte monochrome */
+        if (im->has_alpha)
           {
-             if (mm_read(data, w * 1))
-                goto quit;
+             data = "" * sizeof(uint8_t) * w);
+             if (!data)
+                QUIT_WITH_RC(LOAD_OOM);
 
-             ptr = data;
-             if (v == 0 || v == 255)
+             ptr2 = im->data;
+             for (y = 0; y < h; y++)
                {
+                  if (mm_read(data, w * 2))
+                     goto quit;
+
+                  ptr = data;
                   for (x = 0; x < w; x++)
                     {
                        *ptr2 =
-                          0xff000000 | (ptr[0] << 16) | (ptr[0] << 8) | ptr[0];
+                          (ptr[1] ? 0xff000000 : 0) | (ptr[0] ? 0xffffff : 0);
                        ptr2++;
-                       ptr++;
+                       ptr += 2;
                     }
                }
-             else
+
+             if (im->lc && __imlib_LoadProgressRows(im, y, 1))
+                goto quit_progress;
+          }
+        else
+          {
+             data = "" * sizeof(uint8_t) * w);
+             if (!data)
+                QUIT_WITH_RC(LOAD_OOM);
+
+             ptr2 = im->data;
+             for (y = 0; y < h; y++)
                {
+                  if (mm_read(data, w * 1))
+                     goto quit;
+
+                  ptr = data;
                   for (x = 0; x < w; x++)
                     {
-                       *ptr2 =
-                          0xff000000 |
-                          (((ptr[0] * 255) / v) << 16) |
-                          (((ptr[0] * 255) / v) << 8) | ((ptr[0] * 255) / v);
+                       *ptr2 = 0xff000000 | (ptr[0] ? 0xffffff : 0);
                        ptr2++;
                        ptr++;
                     }
@@ -338,46 +493,180 @@ _load(ImlibImage * im, int load_data)
                 goto quit_progress;
           }
         break;
-     case '6':                 /* 24bit binary RGBRGBRGB */
-        data = "" * sizeof(uint8_t) * w);
-        if (!data)
-           QUIT_WITH_RC(LOAD_OOM);
 
-        ptr2 = im->data;
-        for (y = 0; y < h; y++)
+     case GRAY_RAW:            /* binary 8bit grayscale GGGGGGGG */
+        if (im->has_alpha)
           {
-             if (mm_read(data, w * 3))
-                goto quit;
+             data = "" * sizeof(uint8_t) * w);
+             if (!data)
+                QUIT_WITH_RC(LOAD_OOM);
 
-             ptr = data;
-             if (v == 0 || v == 255)
+             ptr2 = im->data;
+             for (y = 0; y < h; y++)
                {
-                  for (x = 0; x < w; x++)
+                  if (mm_read(data, w * 2))
+                     goto quit;
+
+                  ptr = data;
+                  if (v == 0 || v == 255)
                     {
-                       *ptr2 =
-                          0xff000000 | (ptr[0] << 16) | (ptr[1] << 8) | ptr[2];
-                       ptr2++;
-                       ptr += 3;
+                       for (x = 0; x < w; x++)
+                         {
+                            *ptr2 =
+                               (ptr[1] << 24) | (ptr[0] << 16) | (ptr[0] << 8) |
+                               ptr[0];
+                            ptr2++;
+                            ptr += 2;
+                         }
                     }
+                  else
+                    {
+                       for (x = 0; x < w; x++)
+                         {
+                            *ptr2 =
+                               (((ptr[1] * 255) / v) << 24) |
+                               (((ptr[0] * 255) / v) << 16) |
+                               (((ptr[0] * 255) / v) << 8) | ((ptr[0] * 255) /
+                                                              v);
+                            ptr2++;
+                            ptr += 2;
+                         }
+                    }
+
+                  if (im->lc && __imlib_LoadProgressRows(im, y, 1))
+                     goto quit_progress;
                }
-             else
+          }
+        else
+          {
+             data = "" * sizeof(uint8_t) * w);
+             if (!data)
+                QUIT_WITH_RC(LOAD_OOM);
+
+             ptr2 = im->data;
+             for (y = 0; y < h; y++)
                {
-                  for (x = 0; x < w; x++)
+                  if (mm_read(data, w * 1))
+                     goto quit;
+
+                  ptr = data;
+                  if (v == 0 || v == 255)
                     {
-                       *ptr2 =
-                          0xff000000 |
-                          (((ptr[0] * 255) / v) << 16) |
-                          (((ptr[1] * 255) / v) << 8) | ((ptr[2] * 255) / v);
-                       ptr2++;
-                       ptr += 3;
+                       for (x = 0; x < w; x++)
+                         {
+                            *ptr2 =
+                               0xff000000 | (ptr[0] << 16) | (ptr[0] << 8) |
+                               ptr[0];
+                            ptr2++;
+                            ptr++;
+                         }
+                    }
+                  else
+                    {
+                       for (x = 0; x < w; x++)
+                         {
+                            *ptr2 =
+                               0xff000000 |
+                               (((ptr[0] * 255) / v) << 16) |
+                               (((ptr[0] * 255) / v) << 8) | ((ptr[0] * 255) /
+                                                              v);
+                            ptr2++;
+                            ptr++;
+                         }
                     }
+
+                  if (im->lc && __imlib_LoadProgressRows(im, y, 1))
+                     goto quit_progress;
                }
+          }
+        break;
 
-             if (im->lc && __imlib_LoadProgressRows(im, y, 1))
-                goto quit_progress;
+     case RGB_RAW:             /* 24bit binary RGBRGBRGB */
+        if (im->has_alpha)
+          {
+             data = "" * sizeof(uint8_t) * w);
+             if (!data)
+                QUIT_WITH_RC(LOAD_OOM);
+
+             ptr2 = im->data;
+             for (y = 0; y < h; y++)
+               {
+                  if (mm_read(data, w * 4))
+                     goto quit;
+
+                  ptr = data;
+                  if (v == 0 || v == 255)
+                    {
+                       for (x = 0; x < w; x++)
+                         {
+                            *ptr2 = PIXEL_ARGB(ptr[3], ptr[0], ptr[1], ptr[2]);
+                            ptr2++;
+                            ptr += 4;
+                         }
+                    }
+                  else
+                    {
+                       for (x = 0; x < w; x++)
+                         {
+                            *ptr2 =
+                               PIXEL_ARGB((ptr[3] * 255) / v,
+                                          (ptr[0] * 255) / v,
+                                          (ptr[1] * 255) / v,
+                                          (ptr[2] * 255) / v);
+                            ptr2++;
+                            ptr += 4;
+                         }
+                    }
+
+                  if (im->lc && __imlib_LoadProgressRows(im, y, 1))
+                     goto quit_progress;
+               }
+          }
+        else
+          {
+             data = "" * sizeof(uint8_t) * w);
+             if (!data)
+                QUIT_WITH_RC(LOAD_OOM);
+
+             ptr2 = im->data;
+             for (y = 0; y < h; y++)
+               {
+                  if (mm_read(data, w * 3))
+                     goto quit;
+
+                  ptr = data;
+                  if (v == 0 || v == 255)
+                    {
+                       for (x = 0; x < w; x++)
+                         {
+                            *ptr2 =
+                               0xff000000 | (ptr[0] << 16) | (ptr[1] << 8) |
+                               ptr[2];
+                            ptr2++;
+                            ptr += 3;
+                         }
+                    }
+                  else
+                    {
+                       for (x = 0; x < w; x++)
+                         {
+                            *ptr2 =
+                               0xff000000 |
+                               (((ptr[0] * 255) / v) << 16) |
+                               (((ptr[1] * 255) / v) << 8) | ((ptr[2] * 255) /
+                                                              v);
+                            ptr2++;
+                            ptr += 3;
+                         }
+                    }
+
+                  if (im->lc && __imlib_LoadProgressRows(im, y, 1))
+                     goto quit_progress;
+               }
           }
         break;
-     case '7':                 /* XV's 8bit 332 format */
+
+     case XV332:               /* XV's 8bit 332 format */
         data = "" * sizeof(uint8_t) * w);
         if (!data)
            QUIT_WITH_RC(LOAD_OOM);
@@ -409,44 +698,7 @@ _load(ImlibImage * im, int load_data)
                 goto quit_progress;
           }
         break;
-     case '8':                 /* 24bit binary RGBARGBARGBA */
-        data = "" * sizeof(uint8_t) * w);
-        if (!data)
-           QUIT_WITH_RC(LOAD_OOM);
-
-        ptr2 = im->data;
-        for (y = 0; y < h; y++)
-          {
-             if (mm_read(data, w * 4))
-                goto quit;
 
-             ptr = data;
-             if (v == 0 || v == 255)
-               {
-                  for (x = 0; x < w; x++)
-                    {
-                       *ptr2 = PIXEL_ARGB(ptr[3], ptr[0], ptr[1], ptr[2]);
-                       ptr2++;
-                       ptr += 4;
-                    }
-               }
-             else
-               {
-                  for (x = 0; x < w; x++)
-                    {
-                       *ptr2 =
-                          PIXEL_ARGB((ptr[3] * 255) / v,
-                                     (ptr[0] * 255) / v,
-                                     (ptr[1] * 255) / v, (ptr[2] * 255) / v);
-                       ptr2++;
-                       ptr += 4;
-                    }
-               }
-
-             if (im->lc && __imlib_LoadProgressRows(im, y, 1))
-                goto quit_progress;
-          }
-        break;
      default:
         goto quit;
       quit_progress:

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to