]> bicyclesonthemoon.info Git - ott/enhance/blobdiff - pal_unmix.c
debug build target; updated config tool; install script
[ott/enhance] / pal_unmix.c
index 3dd211cc8ea0ba47fbaf4c46d504c2524a870566..2340a8cc93d9b3fedf98be1b98c7aed3a059d36c 100644 (file)
-// extract.c\r
-// The tool to extract two images hidden iside one indexed image\r
-// 25.06.2015\r
-// \r
-// Copyright (C) 2015  Balthasar Szczepański\r
-// \r
-// This program is free software: you can redistribute it and/or modify\r
-// it under the terms of the GNU Affero General Public License as\r
-// published by the Free Software Foundation, either version 3 of the\r
-// License, or (at your option) any later version.\r
-// \r
-// This program is distributed in the hope that it will be useful,\r
-// but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-// GNU Affero General Public License for more details.\r
-// \r
-// You should have received a copy of the GNU Affero General Public License\r
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
-// \r
+/*\r
+pal_unmix.c\r
+The tool to extract two images hidden iside one indexed image\r
+03.12.2022\r
 \r
-// Requires Dev Image Library (libdevil) (http://openil.sourceforge.net/)\r
-// on Pentium III libdevil must be recompiled with\r
-// --disable-ssl2 --disable-ssl3\r
-// (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=572954)\r
+Copyright (C) 2015, 2022  Balthasar Szczepański\r
 \r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include "IL/il.h"\r
+This program is free software: you can redistribute it and/or modify\r
+it under the terms of the GNU Affero General Public License as\r
+published by the Free Software Foundation, either version 3 of the\r
+License, or (at your option) any later version.\r
 \r
-int mustard(const char *t,int m,int e);\r
-int main(int argc, char *argv[]);\r
-//unsigned short psqrt(unsigned short s);\r
-unsigned short tsqrt(unsigned short s);\r
+This program is distributed in the hope that it will be useful,\r
+but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+GNU Affero General Public License for more details.\r
 \r
-ILuint inpix, outpix1, outpix2;\r
-unsigned char q =0;\r
+You should have received a copy of the GNU Affero General Public License\r
+along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
 \r
 \r
+Requires Dev Image Library (libdevil) (http://openil.sourceforge.net/)\r
+on Pentium III libdevil must be recompiled with\r
+--disable-ssl2 --disable-ssl3\r
+(https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=572954)\r
 \r
-int main(int argc, char *argv[])\r
+*/\r
+\r
+#include <stdint.h>\r
+#include <getopt.h>\r
+#include <errno.h>\r
+\r
+#include "core.h"\r
+#include "pal_unmix.h"\r
+\r
+int palette_unmix_index (ILuint n, struct PixelInfo *p, void *data);\r
+\r
+char PAL_UNMIX_MISSING_ARGS[] = "Missing parameters.\npal_unmix inPix outPix1 outPix2 [n1 n2]\n";\r
+\r
+int subtool_pal_unmix (int argc, char **argv, int argi, char **err)\r
 {\r
+       uint_fast16_t id[3] = {0, 1, 2};\r
+       ILint xyf0[3] = {0, 0, 0};\r
+       struct IL_full_info info[3];\r
+       FLAG_TYPE flags[3] = {\r
+               MUST_BE_INDEXED | NOT_READABLE | CAN_BE_MULTIPLE,\r
+               MUST_BE_INDEXED | NOT_READABLE | CAN_BE_MULTIPLE,\r
+               MUST_BE_INDEXED | NOT_WRITABLE | CAN_BE_MULTIPLE\r
+       };\r
+       ILubyte new_pal0[0x100 * 4];\r
+       ILubyte new_pal1[0x100 * 4];\r
+       ILubyte *pal2;\r
+       ILubyte *rd, *wr;\r
+       ILuint n0, n1, n;\r
+       uint_fast8_t size_defined = 0;\r
+       ILuint i, j, k;\r
+       int r;\r
        \r
-       ILubyte *pal, *data1, *data2, *data;\r
-       ILubyte pal12[16*3];\r
-       unsigned short i;\r
-       unsigned long k;\r
-       ILuint col12, col,  x, y;\r
-       \r
-       if (argc<4)\r
-               return mustard("extract inpix outpix1 outpix2 [q]",0,1);\r
-       else if (argc>4)\r
-               q=1;\r
-       ilInit();\r
-               \r
-       ilEnable(IL_ORIGIN_SET);\r
-       ilEnable(IL_FILE_OVERWRITE);\r
-       \r
-       ilGenImages(1,&inpix);\r
-       ilGenImages(1,&outpix1);\r
-       ilGenImages(1,&outpix2);\r
-       \r
-       ilBindImage(inpix);\r
-       if(!ilLoadImage(argv[1]))\r
-               return mustard("inpix load fail.",1,1);\r
-       if(ilGetInteger(IL_IMAGE_FORMAT)!=IL_COLOUR_INDEX)\r
-               return mustard("inpix not indexed.",1,1);\r
-       ilConvertPal(IL_PAL_RGB24);\r
-       col=ilGetInteger(IL_PALETTE_NUM_COLS);\r
-       col12=tsqrt(col);\r
-       if(!col12)\r
-               return mustard("Palette is not squarish.",1,1);\r
-       x=ilGetInteger(IL_IMAGE_WIDTH);\r
-       y=ilGetInteger(IL_IMAGE_HEIGHT);\r
-       pal=ilGetPalette();\r
-       data=ilGetData();\r
-       \r
-       for(i=0;i<col12;++i)\r
+       if (argc < argi + 3)\r
        {\r
-               pal12[3*i  ]=pal[3*i*(col12+1)  ];\r
-               pal12[3*i+1]=pal[3*i*(col12+1)+1];\r
-               pal12[3*i+2]=pal[3*i*(col12+1)+2];\r
+               *err = PAL_UNMIX_MISSING_ARGS;\r
+               return EINVAL;\r
        }\r
        \r
-       ilBindImage(outpix1);\r
-       if(!ilTexImage(x,y,1,1,IL_COLOUR_INDEX,IL_UNSIGNED_BYTE,NULL))\r
-               return mustard ("outpix1 create fail.",1,1);\r
-       ilRegisterPal(pal12,col12*3,IL_PAL_RGB24);\r
-       data1=ilGetData();\r
+       if (argc >= argi + 5)\r
+       {\r
+               sscanf(argv[argi+3],"%u",&n0);\r
+               sscanf(argv[argi+4],"%u",&n1);\r
+               n = n0 * n1;\r
+               size_defined = 1;\r
+       }\r
+       \r
+       r = reserve_pictures(3);\r
+       if (r)\r
+       {\r
+               *err = CREATE_FAILED;\r
+               return r;\r
+       }\r
        \r
-       ilBindImage(outpix2);\r
-       if(!ilTexImage(x,y,1,1,IL_COLOUR_INDEX,IL_UNSIGNED_BYTE,NULL))\r
-               return mustard ("outpix2 create fail.",1,1);\r
-       ilRegisterPal(pal12,col12*3,IL_PAL_RGB24);\r
-       data2=ilGetData();\r
+       r = load_picture(2, argv[argi], &(info[2]), &(flags[2]));\r
+       if (r)\r
+       {\r
+               *err = LOAD_FAILED;\r
+               return r;\r
+       }\r
        \r
-       for(k=0;k<x*y;++k)\r
+       if (size_defined)\r
+       {\r
+               if (info[2].palette_num_cols < n)\r
+               {\r
+                       *err = BAD_PALETTE_SIZE;\r
+                       return EINVAL;\r
+               }\r
+       }\r
+       else\r
        {\r
-               data1[k]=data[k]/col12;\r
-               data2[k]=data[k]%col12;\r
+               n = info[2].palette_num_cols;\r
+               n0 = tsqrt(n);\r
+               if (n0 == 0)\r
+               {\r
+                       *err = BAD_PALETTE_SIZE;\r
+                       return EINVAL;\r
+               }\r
+               n1 = n0;\r
        }\r
        \r
-       if(!ilSave(IL_PNG,argv[3]))\r
-               return mustard("outpix2 save fail",1,1);\r
-       ilBindImage(outpix1);              \r
-       if(!ilSave(IL_PNG,argv[2]))\r
-               return mustard("outpix1 save fail",1,1);\r
-                               \r
-       return mustard("Ok",1,0);\r
+       if (flags[2] & HAS_ALPHA)\r
+       {\r
+               flags[0] |= MUST_HAVE_ALPHA;\r
+               flags[1] |= MUST_HAVE_ALPHA;\r
+       }\r
+       else\r
+       {\r
+               flags[0] |= CANNOT_HAVE_ALPHA;\r
+               flags[1] |= CANNOT_HAVE_ALPHA;\r
+       }\r
        \r
+       r = build_picture_from_info(0, &(info[2]), &(info[0]), &(flags[0]));\r
+       if (r!=0)\r
+       {\r
+               *err = CREATE_FAILED;\r
+               return EIO;\r
+       }\r
        \r
-}\r
-\r
-int mustard(const char *t, int m,int e)\r
-{\r
-       if(!q)puts(t);\r
-       switch (m)\r
-  {\r
-  case 1:\r
-       ilDeleteImages(1,&inpix);\r
-               ilDeleteImages(1,&outpix1);\r
-               ilDeleteImages(1,&outpix2);\r
-  case 0:\r
-  default:\r
-               return e;\r
+       r = build_picture_from_info(1, &(info[2]), &(info[1]), &(flags[1]));\r
+       if (r!=0)\r
+       {\r
+               *err = CREATE_FAILED;\r
+               return EIO;\r
+       }\r
+       \r
+       /* create palettes - I didn't define separate action of this type */\r
+       \r
+       for (i=0; i<=info[2].num_images; ++i)\r
+       {\r
+               r = get_palette(2, &pal2, i);\r
+               if (r!=0)\r
+               {\r
+                       *err = CONVERT_FAILED;\r
+                       return EIO;\r
+               }\r
+               \r
+               wr = new_pal0;\r
+               for (j=0; j<n0; ++j)\r
+               {\r
+                       rd = pal2 + ((2*(j*(n-1))+1)/(2*(n0-1))) * info[2].palette_bpp;\r
+                       for (k=0; k<info[2].palette_bpp; ++k)\r
+                       {\r
+                               *wr = *rd;\r
+                               ++wr;\r
+                               ++rd;\r
+                       }\r
+               }\r
+               wr = new_pal1;\r
+               for (j=0; j<n1; ++j)\r
+               {\r
+                       rd = pal2 + ((2*(j*(n-1))+1)/(2*(n1-1))) * info[2].palette_bpp;\r
+                       for (k=0; k<info[2].palette_bpp; ++k)\r
+                       {\r
+                               *wr = *rd;\r
+                               ++wr;\r
+                               ++rd;\r
+                       }\r
+               }\r
+               \r
+               r = set_palette (\r
+                       0,\r
+                       new_pal0,\r
+                       n0 * info[2].palette_bpp,\r
+                       info[2].palette_type,\r
+                       i\r
+               );\r
+               if (r!=0)\r
+               {\r
+                       *err = CONVERT_FAILED;\r
+                       return EIO;\r
+               }\r
+               \r
+               r = set_palette (\r
+                       1,\r
+                       new_pal1,\r
+                       n1 * info[2].palette_bpp,\r
+                       info[2].palette_type,\r
+                       i\r
+               );\r
+               if (r!=0)\r
+               {\r
+                       *err = CONVERT_FAILED;\r
+                       return EIO;\r
+               }\r
+       }\r
+       \r
+       r = perform_action(\r
+               3,\r
+               id,\r
+               xyf0, xyf0, xyf0,\r
+               0, 0, 0,\r
+               &palette_unmix_index,\r
+               flags,\r
+               &n1\r
+       );\r
+       if (r)\r
+       {\r
+               *err = CONVERT_FAILED;\r
+               return r;\r
+       }\r
+       \r
+       r = save_picture(0, argv[argi+1], flags[0]);\r
+       if (r!=0)\r
+       {\r
+               *err = SAVE_FAILED;\r
+               return r;\r
+       }\r
+       \r
+       r = save_picture(1, argv[argi+2], flags[1]);\r
+       if (r!=0)\r
+       {\r
+               *err = SAVE_FAILED;\r
+               return r;\r
        }\r
+       \r
+       return 0;\r
 }\r
 \r
-unsigned short tsqrt(unsigned short s)\r
+int palette_unmix_index (ILuint n, struct PixelInfo *p, void *data)\r
 {\r
-       switch(s)\r
-       {\r
-       case 256:\r
-               return 16;\r
-       case 225:\r
-               return 15;\r
-       case 196:\r
-               return 14;\r
-       case 169:\r
-               return 13;\r
-       case 144:\r
-               return 12;\r
-       case 121:\r
-               return 11;\r
-       case 100:\r
-               return 10;\r
-       case 81:\r
-               return 9;\r
-       case 64:\r
-               return 8;\r
-       case 49:\r
-               return 7;\r
-       case 36:\r
-               return 6;\r
-       case 25:\r
-               return 5;\r
-       case 16:\r
-               return 4;\r
-       case 9:\r
-               return 3;\r
-       case 4:\r
-               return 2;\r
-       case 1:\r
-               return 1;\r
-       default:\r
-               return 0;\r
-       }\r
-}       \r
-//unsigned short isqrt(unsigned s)\r
-//{\r
-//      unsigned short r;\r
-//      unsigned short b=0x0040;\r
-//      \r
-//      while(b>s)\r
-//           b>>=2;\r
-//      while(b)\r
-//      {\r
-//           if(s>=r+b)\r
-//           {\r
-//                   s-=r+b;\r
-//                   r=(r>>1)+b;\r
-//           }\r
-//           else\r
-//                   r>>1;\r
-//           b>>2;\r
-//      }\r
-//      return r;\r
-//}\r
+       ILuint *d = data;\r
+       \r
+       if (n < 3)\r
+               return EIO;\r
+       \r
+       p[0].index = p[2].index / *d;\r
+       p[1].index = p[2].index % *d;\r
+       \r
+       return 0;\r
+}\r