]> bicyclesonthemoon.info Git - ott/enhance/blob - pal_mixdiff.c
use config tool as submodule
[ott/enhance] / pal_mixdiff.c
1 /*\r
2 pal_mixdiff.c\r
3 The tool to see difference between two images hidden iside one indexed image\r
4 03.12.2022\r
5 \r
6 Copyright (C) 2015, 2022  Balthasar Szczepański\r
7 \r
8 This program is free software: you can redistribute it and/or modify\r
9 it under the terms of the GNU Affero General Public License as\r
10 published by the Free Software Foundation, either version 3 of the\r
11 License, or (at your option) any later version.\r
12 \r
13 This program is distributed in the hope that it will be useful,\r
14 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
16 GNU Affero General Public License for more details.\r
17 \r
18 You should have received a copy of the GNU Affero General Public License\r
19 along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
20 \r
21 \r
22 Requires Dev Image Library (libdevil) (http://openil.sourceforge.net/)\r
23 on Pentium III libdevil must be recompiled with\r
24 --disable-ssl2 --disable-ssl3\r
25 (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=572954)\r
26 \r
27 */\r
28 \r
29 #include <stdint.h>\r
30 #include <getopt.h>\r
31 #include <errno.h>\r
32 \r
33 #include "core.h"\r
34 #include "pal_mixdiff.h"\r
35 \r
36 int palette_mixdiff_index (ILuint n, struct PixelInfo *p, void *data);\r
37 \r
38 char PAL_MIXDIFF_MISSING_ARGS[] = "Missing parameters.\npal_mixdiff inPix outPix [n1 n2]\n";\r
39 \r
40 int subtool_pal_mixdiff (int argc, char **argv, int argi, char **err)\r
41 {\r
42         struct IL_full_info info;\r
43         FLAG_TYPE flags = MUST_BE_INDEXED | CAN_BE_MULTIPLE;\r
44         ILubyte new_pal[0x100 * 4];\r
45         ILubyte *pal;\r
46         ILubyte *rd, *wr;\r
47         ILuint n0, n1, n;\r
48         uint_fast8_t size_defined = 0;\r
49         ILuint i, j, k;\r
50         ILuint max_index = 0;\r
51         int r;\r
52         \r
53         if (argc < argi + 2)\r
54         {\r
55                 *err = PAL_MIXDIFF_MISSING_ARGS;\r
56                 return EINVAL;\r
57         }\r
58         \r
59         if (argc >= argi + 4)\r
60         {\r
61                 sscanf(argv[argi+2],"%u",&n0);\r
62                 sscanf(argv[argi+3],"%u",&n1);\r
63                 n = n0 * n1;\r
64                 size_defined = 1;\r
65         }\r
66         \r
67         r = reserve_pictures(1);\r
68         if (r)\r
69         {\r
70                 *err = CREATE_FAILED;\r
71                 return r;\r
72         }\r
73         \r
74         r = load_picture(0, argv[argi], &info, &flags);\r
75         if (r)\r
76         {\r
77                 *err = LOAD_FAILED;\r
78                 return r;\r
79         }\r
80         \r
81         if (size_defined)\r
82         {\r
83                 if (info.palette_num_cols < n)\r
84                 {\r
85                         *err = BAD_PALETTE_SIZE;\r
86                         return EINVAL;\r
87                 }\r
88         }\r
89         else\r
90         {\r
91                 n = info.palette_num_cols;\r
92                 n0 = tsqrt(n);\r
93                 if (n0 == 0)\r
94                 {\r
95                         *err = BAD_PALETTE_SIZE;\r
96                         return EINVAL;\r
97                 }\r
98                 n1 = n0;\r
99         }\r
100         \r
101         /* inefficiently find max index */\r
102         for (i=0; i<n0; ++i)\r
103         {\r
104                 for (j=0; j<n1; ++j)\r
105                 {\r
106                         k = i ^ j;\r
107                         if (max_index < k)\r
108                                 max_index = k;\r
109                 }\r
110         }\r
111         \r
112         /* create palettes - I didn't define separate action of this type */\r
113         \r
114         for (i=0; i<=info.num_images; ++i)\r
115         {\r
116                 r = get_palette(0, &pal, i);\r
117                 if (r!=0)\r
118                 {\r
119                         *err = CONVERT_FAILED;\r
120                         return EIO;\r
121                 }\r
122                 \r
123                 wr = new_pal;\r
124                 for (j=0; j<=max_index; ++j)\r
125                 {\r
126                         rd = pal + ((2*(j*(n-1))+1)/(2*max_index)) * info.palette_bpp;\r
127                         for (k=0; k<info.palette_bpp; ++k)\r
128                         {\r
129                                 *wr = *rd;\r
130                                 ++wr;\r
131                                 ++rd;\r
132                         }\r
133                 }\r
134                 \r
135                 r = set_palette (\r
136                         0,\r
137                         new_pal,\r
138                         (max_index+1) * info.palette_bpp,\r
139                         info.palette_type,\r
140                         i\r
141                 );\r
142                 if (r!=0)\r
143                 {\r
144                         *err = CONVERT_FAILED;\r
145                         return EIO;\r
146                 }\r
147         }\r
148         \r
149         r = perform_action_1picture(\r
150                 0,\r
151                 0, 0, 0,\r
152                 0, 0, 0,\r
153                 &palette_mixdiff_index,\r
154                 flags,\r
155                 &n1\r
156         );\r
157         if (r)\r
158         {\r
159                 *err = CONVERT_FAILED;\r
160                 return r;\r
161         }\r
162         \r
163         r = save_picture(0, argv[argi+1], flags);\r
164         if (r!=0)\r
165         {\r
166                 *err = SAVE_FAILED;\r
167                 return r;\r
168         }\r
169         \r
170         return 0;\r
171 }\r
172 \r
173 int palette_mixdiff_index (ILuint n, struct PixelInfo *p, void *data)\r
174 {\r
175         ILuint *d = data;\r
176         \r
177         p->index = (p->index / *d) ^ (p->index % *d);\r
178         \r
179         return 0;\r
180 }\r