-// 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
+01.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_mix.h"\r
+\r
+int palette_unmix_index (ILuint n, struct PixelInfo *p, void *data);\r
+ILuint tsqrt(ILuint s);\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
+ *err = PAL_UNMIX_MISSING_ARGS;\r
+ return EINVAL;\r
+ }\r
+ \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
+ r = load_picture(2, argv[argi], &(info[2]), &(flags[2]));\r
+ if (r)\r
+ {\r
+ *err = LOAD_FAILED;\r
+ return r;\r
+ }\r
+ \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
+ 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 (flags[2] & HAS_ALPHA)\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
+ 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
- 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
+ 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
- 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
+ /* create palettes - I didn't define separate action of this type */\r
\r
- for(k=0;k<x*y;++k)\r
+ for (i=0; i<=info[2].num_images; ++i)\r
{\r
- data1[k]=data[k]/col12;\r
- data2[k]=data[k]%col12;\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
- 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
+ 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
-int mustard(const char *t, int m,int e)\r
+int palette_unmix_index (ILuint n, struct PixelInfo *p, void *data)\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
+ 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
\r
-unsigned short tsqrt(unsigned short s)\r
+ILuint tsqrt(ILuint s)\r
{\r
switch(s)\r
{\r
return 2;\r
case 1:\r
return 1;\r
- default:\r
+ default: // not a square - please fail\r
return 0;\r
}\r
-} \r
+}\r
+\r
//unsigned short isqrt(unsigned s)\r
//{\r
// unsigned short r;\r