1 /* memory.h
2 Copyright (C) 2004-2021 Mark Tyler and Dmitry Groshev
3
4 This file is part of mtPaint.
5
6 mtPaint is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 mtPaint is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with mtPaint in the file COPYING.
18 */
19
20 #include <limits.h>
21 #include <png.h>
22
23 /// Definitions, structures & variables
24
25 #define MAX_WIDTH 16384
26 #define MAX_HEIGHT 16384
27 #define MIN_WIDTH 1
28 #define MIN_HEIGHT 1
29 /* !!! If MAX_WIDTH * MAX_HEIGHT * max bpp won't fit into int, lots of code
30 * !!! will have to be modified to use size_t instead */
31 #define MAX_DIM (MAX_WIDTH > MAX_HEIGHT ? MAX_WIDTH : MAX_HEIGHT)
32
33 #define DEFAULT_WIDTH 640
34 #define DEFAULT_HEIGHT 480
35
36 /* Palette area layout */
37
38 #define PALETTE_SWATCH_X 25
39 #define PALETTE_SWATCH_Y 1
40 #define PALETTE_SWATCH_W 26
41 #define PALETTE_SWATCH_H 16
42 #define PALETTE_INDEX_X 0
43 #define PALETTE_INDEX_DY 5
44 #define PALETTE_DIGIT_W 7
45 #define PALETTE_DIGIT_H 7
46 #define PALETTE_CROSS_X 53
47 #define PALETTE_CROSS_DX 4
48 #define PALETTE_CROSS_DY 4
49 #define PALETTE_CROSS_W 8
50 #define PALETTE_CROSS_H 8
51
52 #define PALETTE_WIDTH 70
53 #define PALETTE_W3 (PALETTE_WIDTH * 3)
54 #define PALETTE_HEIGHT (PALETTE_SWATCH_H * 256 + PALETTE_SWATCH_Y * 2)
55
56 enum {
57 TOOL_SQUARE = 0,
58 TOOL_CIRCLE,
59 TOOL_HORIZONTAL,
60 TOOL_VERTICAL,
61 TOOL_SLASH,
62 TOOL_BACKSLASH,
63 TOOL_SPRAY,
64 TOOL_SHUFFLE,
65 TOOL_FLOOD,
66 TOOL_SELECT,
67 TOOL_LINE,
68 TOOL_SMUDGE,
69 TOOL_POLYGON,
70 TOOL_CLONE,
71 TOOL_GRADIENT,
72
73 TOTAL_CURSORS
74 };
75
76 #define NO_PERIM(T) (((T) == TOOL_FLOOD) || ((T) == TOOL_SELECT) || \
77 ((T) == TOOL_POLYGON) || ((T) == TOOL_GRADIENT))
78
79 #define PROGRESS_LIM 262144
80
81 #define CHN_IMAGE 0
82 #define CHN_ALPHA 1
83 #define CHN_SEL 2
84 #define CHN_MASK 3
85 #define NUM_CHANNELS 4
86
87 #define CMASK_NONE 0
88 #define CMASK_IMAGE (1 << CHN_IMAGE)
89 #define CMASK_ALPHA (1 << CHN_ALPHA)
90 #define CMASK_SEL (1 << CHN_SEL)
91 #define CMASK_MASK (1 << CHN_MASK)
92 #define CMASK_RGBA ((1 << CHN_IMAGE) | (1 << CHN_ALPHA))
93 #define CMASK_ALL ((1 << NUM_CHANNELS) - 1)
94 #define CMASK_CURR (1 << mem_channel)
95 #define CMASK_FOR(A) (1 << (A))
96 #define CMASK_CLIP ((1 << CHN_IMAGE) | (1 << CHN_ALPHA) | (1 << CHN_SEL))
97
98 #define SIZEOF_PALETTE (256 * sizeof(png_color))
99
100 // Both limits should be powers of two
101 #define FRAMES_MIN 16
102 #define FRAMES_MAX (1024 * 1024) /* A million frames should be QUITE enough */
103
104 /* Frame flags */
105 #define FM_DISPOSAL 3 /* Disposal mask */
106 #define FM_DISP_REMOVE 0 /* Remove (make transparent) (default) */
107 #define FM_DISP_LEAVE 1 /* Leave in place */
108 #define FM_DISP_RESTORE 2 /* Restore to previous state */
109 #define FM_NUKE 4 /* Delete this frame at earliest opportunity */
110
111 /* Undo data types */
112 #define UD_FILENAME 0 /* Filename */
113 #define UD_TEMPFILES 1 /* Temp files list */
114 #define NUM_UTYPES 2 /* Should be no larger than 32 */
115 // List in here all types which need freeing
116 #define UD_FREE_MASK (1 << UD_FILENAME)
117
118 typedef unsigned char *chanlist[NUM_CHANNELS];
119
120 typedef struct {
121 chanlist img;
122 png_color *pal;
123 int width, height;
124 int x, y, delay;
125 short cols, bpp, trans;
126 unsigned short flags;
127 } image_frame;
128
129 typedef struct {
130 image_frame *frames; // Pointer to frames array
131 png_color *pal; // Default palette
132 int cur; // Index of current frame
133 int cnt; // Number of frames in use
134 int max; // Total number of frame slots
135 size_t size; // Total used memory (0 means count it anew)
136 } frameset;
137
138 typedef struct {
139 void *store[NUM_UTYPES];
140 unsigned int map;
141 } undo_data;
142
143 typedef struct {
144 chanlist img;
145 png_color *pal_;
146 unsigned char *tileptr;
147 undo_data *dataptr;
148 size_t size;
149 int width, height, flags;
150 short cols, bpp, trans;
151 } undo_item;
152
153 typedef struct {
154 undo_item **items; // Array of pointers to undo frames
155 int pointer; // Index of currently used image on canvas/screen
156 int done; // Undo images that we have behind current image (i.e. possible UNDO)
157 int redo; // Undo images that we have ahead of current image (i.e. possible REDO)
158 int max; // Total number of undo slots
159 size_t size; // Total used memory (0 means count it anew)
160 } undo_stack;
161
162 typedef struct {
163 chanlist img; // Array of pointers to image channels
164 png_color pal[256]; // RGB entries for all 256 palette colours
165 int cols; // Number of colours in the palette: 1..256 or 0 for no image
166 int bpp; // Bytes per pixel = 1 or 3
167 int trans; // Transparent colour index (-1 if none)
168 int width, height; // Image geometry
169 undo_stack undo_; // Image's undo stack
170 char *filename; // File name of file loaded/saved
171 void *tempfiles; // List of up-to-date temp files
172 int changed; // Changed since last load/save flag
173 } image_info;
174
175 typedef struct {
176 int channel; // Current active channel
177 int ics; // Has the centre been set by the user?
178 float ic[2]; // Current centre x,y
179 int tool_pat, tool_pat_B; // Tool pattern number
180 int xbm_hot_x, xbm_hot_y; // Current XBM hot spot
181 char prot_mask[256]; // 256 bytes used for indexed images
182 int prot; // Number of protected colours
183 int col_[2]; // Index for colour A & B
184 png_color col_24[2]; // RGB for colour A & B
185 int iover, aover; // Image hidden / alpha overlayed
186 } image_state;
187
188 /// GRADIENTS
189
190 #define MAX_GRAD 65536
191 #define GRAD_POINTS 256
192
193 typedef struct {
194 /* Base values */
195 int status, xy[4]; // Gradient placement tool
196 int len, rep, ofs; // Gradient length, repeat, and offset
197 int gmode, rmode; // Gradient mode and repeat mode
198 /* Derived values */
199 double wrep, wil1, wil2, xv, yv, wa;
200 int wmode, wrmode;
201 } grad_info;
202
203 typedef struct {
204 char gtype, otype; // Main and opacity gradient types
205 char grev, orev; // Main and opacity reversal flags
206 int vslen, oplen; // Current gradient lengths
207 int cvslen, coplen; // Custom gradient lengths
208 unsigned char *vs, *vsmap; // Current gradient data
209 unsigned char *op, *opmap; // Current gradient opacities
210 } grad_map;
211
212 typedef unsigned char grad_store[(6 + NUM_CHANNELS * 4) * GRAD_POINTS];
213
214 grad_info gradient[NUM_CHANNELS]; // Per-channel gradient placement
215 double grad_path, grad_x0, grad_y0; // Stroke gradient temporaries
216 grad_map graddata[NUM_CHANNELS + 1]; // RGB + per-channel gradient data
217 grad_store gradbytes; // Storage space for custom gradients
218 int grad_opacity; // Preview opacity
219
220 /* Gradient modes */
221 #define GRAD_MODE_NONE 0
222 #define GRAD_MODE_BURST 1
223 #define GRAD_MODE_LINEAR 2
224 #define GRAD_MODE_BILINEAR 3
225 #define GRAD_MODE_RADIAL 4
226 #define GRAD_MODE_SQUARE 5
227 #define GRAD_MODE_ANGULAR 6
228 #define GRAD_MODE_CONICAL 7
229
230 /* Boundary conditions */
231 #define GRAD_BOUND_STOP 0
232 #define GRAD_BOUND_LEVEL 1
233 #define GRAD_BOUND_REPEAT 2
234 #define GRAD_BOUND_MIRROR 3
235 #define GRAD_BOUND_STOP_A 4 /* Stop mode for angular gradient */
236 #define GRAD_BOUND_REP_A 5 /* Repeat mode for same */
237
238 /* Gradient types */
239 #define GRAD_TYPE_RGB 0
240 #define GRAD_TYPE_SRGB 1
241 #define GRAD_TYPE_HSV 2
242 #define GRAD_TYPE_BK_HSV 3
243 #define GRAD_TYPE_CONST 4
244 #define GRAD_TYPE_CUSTOM 5
245
246 #define STROKE_GRADIENT (mem_gradient && (gradient[mem_channel].status == GRAD_NONE))
247
248 /// Bayer ordered dithering
249
250 const unsigned char bayer[16];
251
252 #define BAYER_MASK 15 /* Use 16x16 matrix */
253 #define BAYER(x,y) (bayer[((x) ^ (y)) & BAYER_MASK] * 2 + bayer[(y) & BAYER_MASK])
254
255 /// Tint tool - contributed by Dmitry Groshev, January 2006
256
257 int tint_mode[3]; // [0] = off/on, [1] = add/subtract, [2] = button (none, left, middle, right : 0-3)
258
259 int mem_cselect;
260 int mem_blend;
261 int mem_unmask;
262 int mem_gradient;
263
264 int paint_gamma;
265
266 /// BLEND MODE
267
268 int blend_mode;
269 int blend_src;
270
271 /* Blend modes */
272 enum {
273 /* RGB-only modes */
274 BLEND_NORMAL = 0,
275 BLEND_HUE,
276 BLEND_SAT,
277 BLEND_VALUE,
278 BLEND_COLOR,
279 BLEND_SATPP,
280
281 /* Per-channel modes */
282 BLEND_1BPP, // First one-byte mode
283 BLEND_MULT = BLEND_1BPP,
284 BLEND_DIV,
285 BLEND_SCREEN,
286 // !!! No "Overlay" - it is a reverse "Hard Light"
287 BLEND_DODGE,
288 BLEND_BURN,
289 BLEND_HLIGHT,
290 BLEND_SLIGHT,
291 BLEND_DIFF,
292 BLEND_DARK,
293 BLEND_LIGHT,
294 BLEND_GRAINX,
295 BLEND_GRAINM,
296 BLEND_XHOLD,
297
298 BLEND_NMODES
299 };
300
301 #define BLEND_MMASK 0x3F
302 #define BLEND_XFORM 0x40
303 #define BLEND_REVERSE 0x80
304 #define BLEND_RGBSHIFT 8
305 /* Flags for internal use */
306 #define BLENDF_TINT 0x01000000 /* Tint add */
307 #define BLENDF_TINTM 0x02000000 /* Tint sub */
308 #define BLENDF_IDX 0x04000000 /* Indexed mode */
309 #define BLENDF_INVM 0x08000000 /* Invert mask */
310 #define BLENDF_SET 0x10000000 /* Ignore settings, use parameter */
311
312 /* Blend sources */
313 enum {
314 SRC_NORMAL = 0,
315 SRC_IMAGE,
316 SRC_LAYER
317 };
318
319 /// FLOOD FILL SETTINGS
320
321 double flood_step;
322 int flood_cube, flood_img, flood_slide;
323
324 int smudge_mode;
325
326 /// QUANTIZATION SETTINGS
327
328 int quan_sqrt; // "Diameter based weighting" - use sqrt of pixel count
329
330 /// IMAGE
331
332 #define MIN_UNDO 11 // Number of undo levels + 1
333 #define DEF_UNDO 101
334 #define MAX_UNDO 1001
335
336 int mem_undo_depth; // Current undo depth
337
338 image_info mem_image; // Current image
339
340 #define mem_img mem_image.img
341 #define mem_pal mem_image.pal
342 #define mem_cols mem_image.cols
343 #define mem_img_bpp mem_image.bpp
344 #define mem_xpm_trans mem_image.trans
345 #define mem_width mem_image.width
346 #define mem_height mem_image.height
347
348 #define mem_undo_im_ mem_image.undo_.items
349 #define mem_undo_pointer mem_image.undo_.pointer
350 #define mem_undo_done mem_image.undo_.done
351 #define mem_undo_redo mem_image.undo_.redo
352 #define mem_undo_max mem_image.undo_.max
353
354 #define mem_filename mem_image.filename
355 #define mem_tempfiles mem_image.tempfiles
356 #define mem_changed mem_image.changed
357
358 image_info mem_clip; // Current clipboard
359
360 #define mem_clipboard mem_clip.img[CHN_IMAGE]
361 #define mem_clip_alpha mem_clip.img[CHN_ALPHA]
362 #define mem_clip_mask mem_clip.img[CHN_SEL]
363 #define mem_clip_bpp mem_clip.bpp
364 #define mem_clip_w mem_clip.width
365 #define mem_clip_h mem_clip.height
366
367 // Repurpose the field
368 #define mem_clip_paletted mem_clip.changed
369 #define mem_clip_pal mem_clip.pal
370
371 image_state mem_state; // Current edit settings
372
373 #define mem_channel mem_state.channel
374 #define mem_ic mem_state.ic
375 #define mem_icx mem_state.ic[0]
376 #define mem_icy mem_state.ic[1]
377 #define mem_ics mem_state.ics
378 #define mem_tool_pat mem_state.tool_pat
379 #define mem_tool_pat_B mem_state.tool_pat_B
380 #define mem_xbm_hot_x mem_state.xbm_hot_x
381 #define mem_xbm_hot_y mem_state.xbm_hot_y
382 #define mem_prot_mask mem_state.prot_mask
383 #define mem_prot mem_state.prot
384 #define mem_col_ mem_state.col_
385 #define mem_col_A mem_state.col_[0]
386 #define mem_col_B mem_state.col_[1]
387 #define mem_col_24 mem_state.col_24
388 #define mem_col_A24 mem_state.col_24[0]
389 #define mem_col_B24 mem_state.col_24[1]
390
391 #define hide_image mem_state.iover
392 #define overlay_alpha mem_state.aover
393
394 int mem_clip_x, mem_clip_y; // Clipboard location on canvas
395
396 #define BRUSH_CELL 36
397 #define BRUSH_GRID_W 9
398 #define BRUSH_GRID_H 9
399 #define NUM_BRUSHES (BRUSH_GRID_W * BRUSH_GRID_H)
400 #define PATCH_WIDTH (BRUSH_CELL * BRUSH_GRID_W)
401 #define PATCH_HEIGHT (BRUSH_CELL * BRUSH_GRID_H)
402
403 extern unsigned char mem_brushes[]; // Preset brushes image
404 int mem_brush_list[NUM_BRUSHES][3]; // Preset brushes parameters
405 int mem_nudge; // Nudge pixels per SHIFT+Arrow key during selection/paste
406
407 int mem_undo_limit; // Max MB memory allocation limit
408 int mem_undo_common; // Percent of undo space in common arena
409 int mem_undo_opacity; // Use previous image for opacity calculations?
410
411 int mem_undo_fail; // Undo space shortfall
412
413 /// COLOR TRANSFORM
414
415 typedef struct {
416 int bcsp[6]; // BR, CO, SA, POSTERIZE, GAMMA, Hue
417 int allow[3]; // R/G/B
418 int pmode; // bitwise/truncated/rounded
419 } transform_state;
420
421 transform_state mem_bcsp[2];
422
423 #define BRCOSA_ITEMS 6
424 #define BRCOSA_POSTERIZE 3
425 #define DEF_POSTERIZE(T) ((T) ? 256 : 8) /* truncated/rounded vs bitwise */
426
427 /// THRESHOLD
428
429 enum {
430 XHOLD_MAX = 0,
431 XHOLD_MIN = 1,
432 XHOLD_RED,
433 XHOLD_GREEN,
434 XHOLD_BLUE,
435
436 XHOLD_NMODES
437 };
438
439 typedef struct {
440 int lo, hi, mode;
441 } threshold_state;
442
443 threshold_state mem_ts;
444
445 /// PATTERNS
446
447 int pattern_B; // Let colour B have its own pattern
448 unsigned char *mem_pattern; // Current pattern
449 unsigned char mem_col_pat[8 * 8]; // Indexed 8x8 colourised pattern using colours A & B
450 unsigned char mem_col_pat24[8 * 8 * 3]; // RGB 8x8 colourised pattern using colours A & B
451
452 /// TOOLS
453
454 typedef struct {
455 int type, brush;
456 int var[3]; // Size, flow, opacity
457 } tool_info;
458
459 tool_info tool_state;
460
461 #define tool_type tool_state.type /* Currently selected tool */
462 #define brush_type tool_state.brush /* Last brush tool type */
463 #define tool_size tool_state.var[0]
464 #define tool_flow tool_state.var[1]
465 #define tool_opacity tool_state.var[2] /* Opacity - 255 = solid */
466
467 int pen_down; // Are we drawing? - Used to see if we need to do an UNDO
468 int tool_ox, tool_oy; // Previous tool coords - used by continuous mode
469 int mem_continuous; // Area we painting the static shapes continuously?
470
471 /// PALETTE
472
473 png_color mem_pal_def[256]; // Default palette entries for new image
474 int mem_pal_def_i; // Items in default palette
475 int mem_pal_id_c, mem_pal_ab_c; // Text & A/B highlight colors
476 extern unsigned char mem_pals[]; // RGB screen memory holding current palette
477
478 int mem_background; // Non paintable area
479 int mem_histogram[256];
480
481 /// Number in bounds
482
bounded(int n,int n0,int n1)483 static inline int bounded(int n, int n0, int n1)
484 {
485 return (n < n0 ? n0 : n > n1 ? n1 : n);
486 }
487
488 /// Next power of two
489
nextpow2(unsigned int n)490 static inline unsigned int nextpow2(unsigned int n)
491 {
492 n |= n >> 1; n |= n >> 2; n |= n >> 4; n |= n >> 8; n |= n >> 16;
493 #if UINT_MAX > 0xFFFFFFFFUL
494 n |= n >> 32;
495 #endif
496 return (n + 1);
497 }
498
499 /// Binary logarithm, rounding up
500
nlog2(unsigned int n)501 static inline unsigned int nlog2(unsigned int n)
502 {
503 unsigned int m;
504 #if UINT_MAX > 0xFFFFFFFFUL
505 m = (n >= 0x100000000U) << 5;
506 m += (n >> m >= 0x10000) << 4;
507 #else
508 m = (n >= 0x10000) << 4;
509 #endif
510 m += (n >> m >= 0x100) << 3;
511 m += (n >> m >= 0x10) << 2;
512 m += (0xFFFFAA50U >> ((n >> m) << 1)) & 3;
513 return (m + (n > 1U << m));
514 }
515
516 /// Number of set bits
517
bitcount(unsigned int n)518 static inline unsigned int bitcount(unsigned int n)
519 {
520 unsigned int m;
521 #if UINT_MAX > 0xFFFFFFFFUL
522 n -= (n >> 1) & 0x5555555555555555U;
523 m = n & 0xCCCCCCCCCCCCCCCCU; n = (n ^ m) + (m >> 2);
524 n = (n + (n >> 4)) & 0x0F0F0F0F0F0F0F0FU;
525 n = (n * 0x0101010101010101U) >> 56;
526 #else
527 n -= (n >> 1) & 0x55555555;
528 m = n & 0x33333333; n = m + ((n ^ m) >> 2);
529 n = (n + (n >> 4)) & 0x0F0F0F0F;
530 n = (n * 0x01010101) >> 24;
531 #endif
532 return (n);
533 }
534
535 /// Floored integer division
536
floor_div(int dd,int dr)537 static inline int floor_div(int dd, int dr)
538 {
539 return (dd / dr - (dd % dr < 0)); // optimizes to perfection on x86
540 }
541
542 /// Ceiling integer division
543
ceil_div(int dd,int dr)544 static inline int ceil_div(int dd, int dr)
545 {
546 return (dd / dr + (dd % dr > 0));
547 }
548
549 /// Floored integer modulus
550
floor_mod(int dd,int dr)551 static inline int floor_mod(int dd, int dr)
552 {
553 return (dd - dr * floor_div(dd, dr));
554 }
555
556 /// Table-based translation
557
do_xlate(unsigned char * xlat,unsigned char * data,int len)558 static inline void do_xlate(unsigned char *xlat, unsigned char *data, int len)
559 {
560 int i;
561
562 for (i = 0; i < len; i++) data[i] = xlat[data[i]];
563 }
564
565 /// Copying "x0y0x1y1" quad
566
567 #define copy4(D,S) memcpy(D, S, 4 * sizeof(int))
568
569 /// Block allocator
570
571 typedef struct {
572 char *block;
573 unsigned int here, size;
574 unsigned int minsize, incr;
575 } wjmem;
576
577 wjmem *wjmemnew(int size, int incr);
578 void wjmemfree(wjmem *mem);
579 void *wjmalloc(wjmem *mem, int size, int align);
580
581 /// Simple doubling allocator
582
583 typedef struct {
584 char *buf; // data block
585 int here; // current position
586 int size; // currently allocated
587 } memx2;
588 #define MEMX2_MAX INT_MAX /* How much it can hold */
589
590 size_t getmemx2(memx2 *mem, size_t length);
591 void addstr(memx2 *mem, char *s, int bk);
592 void addchars(memx2 *mem, int c, int l);
593
594 extern char MEM_NONE_[];
595 #define MEM_NONE (void *)MEM_NONE_ /* Non-NULL pointer which means nothing */
596
597 /// Multiblock allocator
598
599 #define MA_ALIGN_MASK 0x03 /* For alignment constraints */
600 #define MA_ALIGN_DEFAULT 0x00
601 #define MA_ALIGN_DOUBLE 0x01
602 #define MA_SKIP_ZEROSIZE 0x04 /* Leave pointers to zero-size areas unchanged */
603 #define MA_FLAG_NONE 0x08 /* Return MEM_NONE if total size is zero */
604
605 void *multialloc(int flags, void *ptr, int size, ...);
606
607 /// Vectorized low-level drawing functions
608
609 void (*put_pixel)(int x, int y);
610 void (*put_pixel_row)(int x, int y, int len, unsigned char *xsel);
611
612 // Intersect two rectangles
613 int clip(int *rxy, int x0, int y0, int x1, int y1, const int *vxy);
614
615 // Intersect outer & inner rectangle, write out what it separates into
616 int clip4(int *rect04, int xo, int yo, int wo, int ho, int xi, int yi, int wi, int hi);
617
618 // Get scaled span of rectangle on X or Y
619 int xy_span(int *rxy, int scale, int yf);
620
621 // Rebase rectangle to origin X, Y
622 void xy_origin(int *rxy, int *vxy, int x, int y);
623
624 /// Line iterator
625
626 /* Indices 0 and 1 are current X and Y, 2 is number of pixels remaining */
627 typedef int linedata[10];
628
629 void line_init(linedata line, int x0, int y0, int x1, int y1);
630 int line_step(linedata line);
631 void line_nudge(linedata line, int x, int y);
632 int line_clip(linedata line, const int *vxy, int *step);
633 void line_flip(linedata line);
634
635 /// Procedures
636
637 // Add one more frame to a frameset
638 int mem_add_frame(frameset *fset, int w, int h, int bpp, int cmask, png_color *pal);
639 // Remove specified frame from a frameset
640 void mem_remove_frame(frameset *fset, int frame);
641 // Empty a frameset
642 void mem_free_frames(frameset *fset);
643
644 void init_istate(image_state *state, image_info *image); // Set initial state of image variables
645 void mem_replace_filename(int layer, char *fname); // Change layer's filename
646 void mem_file_modified(char *fname); // Label file's frames in current layer as changed
647 int init_undo(undo_stack *ustack, int depth); // Create new undo stack of a given depth
648 void update_undo_depth(); // Resize all undo stacks
649
650 void mem_free_chanlist(chanlist img);
651 int cmask_from(chanlist img); // Chanlist to cmask
652
653 int mem_count_all_cols(); // Count all colours - Using main image
654 int mem_count_all_cols_real(unsigned char *im, int w, int h); // Count all colours - very memory greedy
655
656 int mem_cols_used(png_color *pal); // Count and collect colours used in main RGB image
657 int mem_cols_used_real(unsigned char *im, int w, int h, png_color *pal);
658 // Count and collect colours used in RGB chunk
659
660 #define FREE_IMAGE 1
661 #define FREE_UNDO 2
662 #define FREE_ALL 3
663
664 // Clear/remove image data
665 void mem_free_image(image_info *image, int mode);
666
667 #define AI_COPY 1 /* Duplicate source channels, not insert them */
668 #define AI_NOINIT 2 /* Do not initialize source-less channels */
669 #define AI_CLEAR 4 /* Initialize image structure first */
670
671 // Allocate new image data
672 int mem_alloc_image(int mode, image_info *image, int w, int h, int bpp,
673 int cmask, image_info *src);
674 // Allocate space for new image, removing old if needed
675 int mem_new( int width, int height, int bpp, int cmask );
676 // Allocate new clipboard, removing or preserving old as needed
677 int mem_clip_new(int width, int height, int bpp, int cmask, chanlist backup);
678
679 int load_def_palette(char *name);
680 int load_def_patterns(char *name);
681 void mem_init(); // Initialise memory
682
683 // Return the number of bytes used in image + undo stuff
684 size_t mem_used();
685 // Return the number of bytes used in image + undo in all layers
686 size_t mem_used_layers();
687
688 #define FX_EDGE 0
689 #define FX_EMBOSS 2
690 #define FX_SHARPEN 3
691 #define FX_SOFTEN 4
692 #define FX_SOBEL 5
693 #define FX_PREWITT 6
694 #define FX_GRADIENT 7
695 #define FX_ROBERTS 8
696 #define FX_LAPLACE 9
697 #define FX_KIRSCH 10
698 #define FX_ERODE 11
699 #define FX_DILATE 12
700 #define FX_MORPHEDGE 13
701
702 void do_effect( int type, int param ); // 0=edge detect 1=UNUSED 2=emboss
703 void mem_bacteria( int val ); // Apply bacteria effect val times the canvas area
704 void mem_gauss(double radiusX, double radiusY, int gcor);
705 void mem_unsharp(double radius, double amount, int threshold, int gcor);
706 void mem_dog(double radiusW, double radiusN, int norm, int gcor);
707 void mem_kuwahara(int r, int gcor, int detail);
708
709 /* Colorspaces */
710 #define CSPACE_RGB 0
711 #define CSPACE_SRGB 1
712 #define CSPACE_LXN 2
713 #define NUM_CSPACES 3
714
715 /* Distance measures */
716 #define DIST_LINF 0 /* Largest absolute difference (Linf measure) */
717 #define DIST_L1 1 /* Sum of absolute differences (L1 measure) */
718 #define DIST_L2 2 /* Euclidean distance (L2 measure) */
719 #define NUM_DISTANCES 3
720
721 /// PALETTE PROCS
722
723 void mem_pal_load_def(); // Load default palette
724
725 #define mem_pal_copy(A, B) memcpy((A), (B), SIZEOF_PALETTE)
726 void mem_pal_init(); // Initialise whole of palette RGB
727 // Expand palette to RGB triples, pad with 0 if needed
728 void pal2rgb(unsigned char *rgb, png_color *pal, int cnt, int len);
729 // Pack RGB triples into palette
730 void rgb2pal(png_color *pal, unsigned char *rgb, int cnt);
731 double pal2B(png_color *c); // Linear brightness for palette color
732 void mem_greyscale(int gcor); // Convert image to greyscale
733 void do_convert_rgb(int start, int step, int cnt, unsigned char *dest,
734 unsigned char *src, png_color *pal); // Convert image to RGB
735 int mem_convert_indexed(unsigned char *dest, unsigned char *src, int cnt,
736 int cols, png_color *pal); // Convert image to Indexed Palette
737 // Quantize image using Max-Min algorithm
738 int maxminquan(unsigned char *inbuf, int width, int height, int quant_to,
739 png_color *userpal);
740 // Quantize image using PNN algorithm
741 int pnnquan(unsigned char *inbuf, int width, int height, int quant_to,
742 png_color *userpal);
743 // Convert RGB->indexed using error diffusion with variety of options
744 int mem_dither(unsigned char *old, int ncols, short *dither, int cspace,
745 int dist, int limit, int selc, int serpent, int rgb8b, double emult);
746 // Do the same in dumb but fast way
747 int mem_dumb_dither(unsigned char *old, unsigned char *new, png_color *pal,
748 int width, int height, int ncols, int dither);
749 // Set up colors A, B, and pattern for dithering a given RGB color
750 void mem_find_dither(int red, int green, int blue);
751 // Convert image to Indexed Palette using quantize
752 int mem_quantize( unsigned char *old_mem_image, int target_cols, int type );
753 void mem_invert(); // Invert the palette
754 void mem_normalize(); // Normalize contrast in image or palette
755
756 // Clear/set protection (what = NULL - color n, n = -1 - all colors)
757 void mem_mask_setv(int *what, int n, int state);
758 void mem_mask_init(); // Initialise RGB protection mask
759 int mem_protected_RGB(int intcol); // Is this intcol in mask?
760
761 void mem_swap_cols(int redraw); // Swaps colours and update memory
762 void mem_set_trans(int trans); // Set transparent colour and update
763 void mem_get_histogram(int channel); // Calculate how many of each colour index is on the canvas
764 int scan_duplicates(); // Find duplicate palette colours
765 void remove_duplicates(); // Remove duplicate palette colours - call AFTER scan_duplicates
766 int mem_remove_unused_check(); // Check to see if we can remove unused palette colours
767 int mem_remove_unused(); // Remove unused palette colours
768 void mem_bw_pal(png_color *pal, int i1, int i2); // Generate black-to-white palette
769 // Create colour-transformed palette
770 void transform_pal(png_color *pal1, png_color *pal2, int p1, int p2);
771 void mem_pal_sort( int a, int i1, int i2, int rev );
772 // Sort colours in palette 0=luminance, 1=RGB
773
774 void mem_pal_index_move( int c1, int c2 ); // Move index c1 to c2 and shuffle in between up/down
775 void mem_canvas_index_move( int c1, int c2 ); // Similar to palette item move but reworks canvas pixels
776
777 void set_zoom_centre( int x, int y );
778
779 // Nonclassical HSV: H is 0..6, S is 0..1, V is 0..255
780 void rgb2hsv(unsigned char *rgb, double *hsv);
781 void hsv2rgb(unsigned char *rgb, double *hsv);
782
783 //// UNDO
784
785 enum {
786 UNDO_PAL = 0, /* Palette changes */
787 UNDO_XPAL, /* Palette and indexed image changes */
788 UNDO_COL, /* Palette and/or RGB image changes */
789 UNDO_DRAW, /* Changes to current channel / RGBA */
790 UNDO_INV, /* "Invert" operation */
791 UNDO_XFORM, /* Changes to all channels */
792 UNDO_FILT, /* Changes to current channel */
793 UNDO_PASTE, /* Paste operation (current / RGBA) */
794 UNDO_TOOL, /* Same as UNDO_DRAW but respects pen_down */
795 UNDO_TRANS /* Transparent colour change (cumulative) */
796 };
797
798 void mem_undo_next(int mode); // Call this after a draw event but before any changes to image
799 // Get address of previous channel data (or current if none)
800 unsigned char *mem_undo_previous(int channel);
801 void mem_undo_prepare(); // Call this after changes to image, to compress last frame
802
803 void mem_do_undo(int redo); // Undo or redo requested by user
804
805 #define UC_CREATE 0x01 /* Force create */
806 #define UC_NOCOPY 0x02 /* Forbid copy */
807 #define UC_DELETE 0x04 /* Force delete */
808 #define UC_PENDOWN 0x08 /* Respect pen_down */
809 #define UC_GETMEM 0x10 /* Get memory and do nothing */
810 #define UC_ACCUM 0x20 /* Cumulative change */
811 #define UC_RESET 0x40 /* Delete all, create flagged */
812
813 int undo_next_core(int mode, int new_width, int new_height, int new_bpp, int cmask);
814 void update_undo(image_info *image); // Copy image state into current undo frame
815 // Try to allocate a memory block, releasing undo frames if needed
816 void *mem_try_malloc(size_t size);
817
818 //// Drawing Primitives
819
820 int sb_dist; // Distance measure
821 int sb_rect[4]; // Backbuffer placement
822 int init_sb(); // Create shapeburst backbuffer
823 void render_sb(unsigned char *mask); // Render from shapeburst backbuffer
824
825 int mem_clip_mask_init(unsigned char val); // Initialise the clipboard mask
826 // Extract alpha info from RGB clipboard
827 int mem_scale_alpha(unsigned char *img, unsigned char *alpha,
828 int width, int height, int mode);
829 void mem_mask_colors(unsigned char *mask, unsigned char *img, unsigned char v,
830 int width, int height, int bpp, int col0, int col1);
831 void mem_clip_mask_set(unsigned char val); // Mask colours A and B on the clipboard
832 void mem_clip_mask_clear(); // Clear the clipboard mask
833
834 void mem_smudge(int ox, int oy, int nx, int ny);
835
836 // Apply colour transform
837 void do_transform(int start, int step, int cnt, unsigned char *mask,
838 unsigned char *imgr, unsigned char *img0, int m0);
839
840 // Apply thresholding
841 void do_xhold(int start, int step, int cnt, unsigned char *mask,
842 unsigned char *imgr, unsigned char *img0);
843
844 void mem_flip_v(char *mem, char *tmp, int w, int h, int bpp); // Flip image vertically
845 void mem_flip_h( char *mem, int w, int h, int bpp ); // Flip image horizontally
846 int mem_sel_rot( int dir ); // Rotate clipboard 90 degrees
847 int mem_image_rot( int dir ); // Rotate canvas 90 degrees
848
849 // Get new image geometry of rotation. angle = degrees
850 void mem_rotate_geometry(int ow, int oh, double angle, int *nw, int *nh);
851 // Rotate canvas or clipboard by any angle (degrees)
852 int mem_rotate_free(double angle, int type, int gcor, int clipboard);
853 void mem_rotate_free_real(chanlist old_img, chanlist new_img, int ow, int oh,
854 int nw, int nh, int bpp, double angle, int mode, int gcor, int dis_a,
855 int silent);
856
857 #define BOUND_MIRROR 0 /* Mirror image beyond edges */
858 #define BOUND_TILE 1 /* Tiled image beyond edges */
859 #define BOUND_VOID 2 /* Transparency beyond edges */
860
861 // Scale image
862 int mem_image_scale(int nw, int nh, int type, int gcor, int sharp, int bound);
863 int mem_image_scale_real(chanlist old_img, int ow, int oh, int bpp,
864 chanlist new_img, int nw, int nh, int type, int gcor, int sharp);
865 int mem_image_resize(int nw, int nh, int ox, int oy, int mode); // Resize image
866
867 int mem_isometrics(int type);
868
869 void mem_threshold(unsigned char *img, int len, int level); // Threshold channel values
870 void mem_demultiply(unsigned char *img, unsigned char *alpha, int len, int bpp);
871
872 void set_xlate_n(unsigned char *xlat, int n); // Build value rescaling table
873 #define set_xlate(A,B) set_xlate_n((A), (1 << (B)) - 1) /* Bitdepth translation table */
874 int is_filled(unsigned char *data, unsigned char val, int len); // Check if byte array is all one value
875
876 int flood_fill(int x, int y, unsigned int target);
877
878 void sline( int x1, int y1, int x2, int y2 ); // Draw single thickness straight line
879 void tline( int x1, int y1, int x2, int y2, int size ); // Draw size thickness straight line
880 void g_para( int x1, int y1, int x2, int y2, int xv, int yv ); // Draw general parallelogram
881 void f_rectangle( int x, int y, int w, int h ); // Draw a filled rectangle
882 void f_circle( int x, int y, int r ); // Draw a filled circle
883 void mem_ellipse( int x1, int y1, int x2, int y2, int thick ); // Thickness 0 means filled
884
885 // Draw whatever is bounded by two pairs of lines
886 void draw_quad(linedata line1, linedata line2, linedata line3, linedata line4);
887
888 // A couple of shorthands to get an int representation of an RGB colour
889 #define PNG_2_INT(P) (((P).red << 16) + ((P).green << 8) + ((P).blue))
890 #define MEM_2_INT(M,I) (((M)[(I)] << 16) + ((M)[(I) + 1] << 8) + (M)[(I) + 2])
891 #define INT_2_R(A) ((A) >> 16)
892 #define INT_2_G(A) (((A) >> 8) & 0xFF)
893 #define INT_2_B(A) ((A) & 0xFF)
894 #define RGB_2_INT(R,G,B) (((R) << 16) + ((G) << 8) + (B))
895
896 #define MEM_BPP (mem_channel == CHN_IMAGE ? mem_img_bpp : 1)
897 #define BPP(x) ((x) == CHN_IMAGE ? mem_img_bpp : 1)
898 #define IS_INDEXED ((mem_channel == CHN_IMAGE) && (mem_img_bpp == 1))
899
900 /* Whether process_img() needs extra buffer passed in */
901 #define NEED_XBUF_DRAW (mem_blend && (blend_mode & (BLEND_MMASK | BLEND_XFORM)))
902 #define NEED_XBUF_PASTE (NEED_XBUF_DRAW || \
903 ((mem_channel == CHN_IMAGE) && (mem_clip_bpp < mem_img_bpp)))
904
905 void prep_mask(int start, int step, int cnt, unsigned char *mask,
906 unsigned char *mask0, unsigned char *img0);
907 void process_mask(int start, int step, int cnt, unsigned char *mask,
908 unsigned char *alphar, unsigned char *alpha0, unsigned char *alpha,
909 unsigned char *trans, int opacity, int noalpha);
910 void process_img(int start, int step, int cnt, unsigned char *mask,
911 unsigned char *imgr, unsigned char *img0, unsigned char *img,
912 unsigned char *xbuf, int bpp, int blend);
913 void copy_area(image_info *dest, image_info *src, int x, int y);
914
915 // Retroactive masking - by blending with undo frame
916 void mask_merge(unsigned char *old, int channel, unsigned char *mask);
917
918 int pixel_protected(int x, int y); // generic
919 void row_protected(int x, int y, int len, unsigned char *mask);
920 void put_pixel_def( int x, int y ); // generic
921 void put_pixel_row_def(int x, int y, int len, unsigned char *xsel); // generic
922 int get_pixel( int x, int y ); // generic
923 int get_pixel_RGB( int x, int y ); // converter
924 int get_pixel_img( int x, int y ); // from image
925
926 int grad_value(int *dest, int slot, double x);
927 void grad_pixels(int start, int step, int cnt, int x, int y, unsigned char *mask,
928 unsigned char *op0, unsigned char *img0, unsigned char *alpha0);
929 void grad_update(grad_info *grad);
930 void gmap_setup(grad_map *gmap, grad_store gstore, int slot);
931 void grad_def_update(int slot);
932
933 #define GRAD_CUSTOM_DATA(X) ((X) ? GRAD_POINTS * ((X) * 4 + 2) : 0)
934 #define GRAD_CUSTOM_DMAP(X) (GRAD_POINTS * ((X) * 4 + 3))
935 #define GRAD_CUSTOM_OPAC(X) (GRAD_POINTS * ((X) * 4 + 4))
936 #define GRAD_CUSTOM_OMAP(X) (GRAD_POINTS * ((X) * 4 + 5))
937
938 void blend_indexed(int start, int step, int cnt, unsigned char *rgb,
939 unsigned char *img0, unsigned char *img,
940 unsigned char *alpha0, unsigned char *alpha, int opacity);
941
942 // Select colors nearest to A->B gradient
943 int mem_pick_gradient(unsigned char *buf, int cspace, int mode);
944
945 int mem_skew(double xskew, double yskew, int type, int gcor);
946
947 int average_channel(unsigned char *src, int iw, int *vxy);
948 int average_pixels(unsigned char *rgb, unsigned char *alpha, int iw, int *vxy);
949
950 //// SEGMENTATION
951
952 #define SEG_PROGRESS 1
953
954 typedef struct {
955 int which; // Pixel index * 2 + (0 if right / 1 if down)
956 float diff;
957 } seg_edge;
958
959 typedef struct {
960 unsigned int group, cnt;
961 unsigned char rank; // Value is logarithmic, so this is more than enough
962 // unsigned char reserved[3];
963 float threshold;
964 } seg_pixel;
965
966 typedef struct {
967 /* Working set */
968 seg_edge *edges;
969 seg_pixel *pix;
970 int w, h, cnt;
971 int phase; // Which phase is currently valid
972 /* Parameters */
973 int minrank;
974 int minsize;
975 double threshold;
976 } seg_state;
977
978 seg_state *mem_seg_prepare(seg_state *s, unsigned char *img, int w, int h,
979 int flags, int cspace, int dist);
980 int mem_seg_process_chunk(int start, int cnt, seg_state *s);
981 int mem_seg_process(seg_state *s);
982 double mem_seg_threshold(seg_state *s);
983 void mem_seg_scan(unsigned char *dest, int y, int x, int w, int zoom,
984 const seg_state *s);
985 void mem_seg_render(unsigned char *img, const seg_state *s);
986
987 /// REMAPPING COLORS
988
989 enum {
990 MAP_GREY = 0,
991 MAP_GRAD,
992 MAP_PAL,
993 MAP_CLIP
994 };
995
996 void mem_prepare_map(unsigned char *map, int how); // Set up colors for mapping
997 void mem_remap_rgb(unsigned char *map, int what); // Remap V/R/G/B to color
998
999 /// NOISE
1000
1001 void init_perlin(int seed, int xstep, int ystep, int lvl, int maptype);
1002 void do_perlin(int start, int step, int cnt, unsigned char *mask,
1003 unsigned char *imgr, int x, int y);
1004 void mem_perlin();
1005
1006 #define IF_IN_RANGE( x, y ) if ( x>=0 && y>=0 && x<mem_width && y<mem_height )
1007
1008 /*
1009 * Win32 libc (MSVCRT.DLL) violates the C standard as to malloc()'ed memory
1010 * alignment; this macro serves as part of a workaround for that problem
1011 */
1012 #ifdef WIN32
1013 /* Do not want to include an extra header everywhere, for INT_PTR or intptr_t ;
1014 * instead, choosing the wide enough int type directly */
1015 #ifndef _WIN64 /* In 32-bit Win32, pointers fit into ints */
1016 #define ALIGN(p) ((void *)(((int)(p) + sizeof(double) - 1) & (-sizeof(double))))
1017 #else /* In 64-bit, into long longs */
1018 #define ALIGN(p) ((void *)(((long long int)(p) + sizeof(double) - 1) & (-sizeof(double))))
1019 #endif
1020 #else /* No Win32, no problem */
1021 #define ALIGN(p) ((void *)(p))
1022 #endif
1023
1024 /* Reasonably portable pointer alignment macro */
1025
1026 #define ALIGNED(P, N) ((void *)((char *)(P) + \
1027 ((~(unsigned)((char *)(P) - (char *)0) + 1) & ((N) - 1))))
1028
1029 /* Get preferred alignment of a type */
1030
1031 #ifdef __GNUC__ /* Have native implementation */
1032 #define ALIGNOF(X) __alignof__(X)
1033 #else
1034 #define ALIGNOF(X) offsetof(struct {char c; X x;}, x)
1035 #endif
1036
1037 /* x87 FPU uses long doubles internally, which may cause calculation results
1038 * to depend on emitted assembly code, and change in mysterious ways depending
1039 * on source structure and current optimizations.
1040 * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323
1041 * SSE math works with doubles and floats natively, so is free from this
1042 * instability, while a bit less precise.
1043 * We aren't requiring C99 yet, so use GCC's define instead of the C99-standard
1044 * "FLT_EVAL_METHOD" from float.h for deciding which mode is used.
1045 */
1046
1047 #undef NATIVE_DOUBLES
1048 #if defined(__FLT_EVAL_METHOD__) && ((__FLT_EVAL_METHOD__ == 0) || (__FLT_EVAL_METHOD__ == 1))
1049 #define NATIVE_DOUBLES
1050 #endif
1051
1052 /*
1053 * rint() function rounds halfway cases (0.5 etc.) to even, which may cause
1054 * weird results in geometry calculations. And straightforward (int)(X + 0.5)
1055 * may be affected by double-rounding issues on x87 FPU - and in case floor()
1056 * is implemented as compiler intrinsic, the same can happen with it too.
1057 * These macros are for when neither is acceptable.
1058 */
1059 #ifndef NATIVE_DOUBLES /* Have extra precision */
1060 #define WJ_ROUND(I,X) \
1061 { \
1062 const volatile double RounD___ = (X); \
1063 (I) = (int)(RounD___ + 0.5); \
1064 }
1065 #define WJ_FLOOR(I,X) \
1066 { \
1067 const volatile double RounD___ = (X); \
1068 (I) = floor(RounD___); \
1069 }
1070 #else /* Doubles are doubles */
1071 #define WJ_ROUND(I,X) (I) = (int)((X) + 0.5)
1072 #define WJ_FLOOR(I,X) (I) = floor(X)
1073 #endif
1074
1075 /* Tell GCC to remain silent about an uninitialized variable */
1076 #define uninit_(X) X = X
1077