]> git.saurik.com Git - wxWidgets.git/blame - src/gdk_imlib/utils.c
Made NOPCH overridable
[wxWidgets.git] / src / gdk_imlib / utils.c
CommitLineData
c801d85f
KB
1#define _GNU_SOURCE
2
1f0299c1
KB
3#include "../gdk_imlib/gdk_imlib.h"
4#include "../gdk_imlib/gdk_imlib_private.h"
c801d85f
KB
5
6void
7gcalc_map_tables(GdkImlibImage * im)
8{
9 int i;
10 double g, b, c, ii, v;
11
12 if (!im)
13 return;
14
15 g = ((double)im->mod.gamma) / 256;
16 b = ((double)im->mod.brightness) / 256;
17 c = ((double)im->mod.contrast) / 256;
18 if (g < 0.01)
19 g = 0.01;
20
21 for (i = 0; i < 256; i++)
22 {
23 ii = ((double)i) / 256;
24 v = ((ii - 0.5) * c) + 0.5 + (b - 1);
25 if (v > 0)
26 v = pow(((ii - 0.5) * c) + 0.5 + (b - 1), 1 / g) * 256;
27 else
28 v = 0;
29 if (v > 255)
30 v = 255;
31 else if (v < 0)
32 v = 0;
33 im->rmap[i] = (unsigned char)v;
34 im->gmap[i] = (unsigned char)v;
35 im->bmap[i] = (unsigned char)v;
36 }
37 g = ((double)im->rmod.gamma) / 256;
38 b = ((double)im->rmod.brightness) / 256;
39 c = ((double)im->rmod.contrast) / 256;
40 if (g < 0.01)
41 g = 0.01;
42
43 for (i = 0; i < 256; i++)
44 {
45 ii = ((double)im->rmap[i]) / 256;
46 v = ((ii - 0.5) * c) + 0.5 + (b - 1);
47 if (v > 0)
48 v = pow(((ii - 0.5) * c) + 0.5 + (b - 1), 1 / g) * 256;
49 else
50 v = 0;
51 if (v > 255)
52 v = 255;
53 else if (v < 0)
54 v = 0;
55 im->rmap[i] = (unsigned char)v;
56 }
57 g = ((double)im->gmod.gamma) / 256;
58 b = ((double)im->gmod.brightness) / 256;
59 c = ((double)im->gmod.contrast) / 256;
60 if (g < 0.01)
61 g = 0.01;
62
63 for (i = 0; i < 256; i++)
64 {
65 ii = ((double)im->gmap[i]) / 256;
66 v = ((ii - 0.5) * c) + 0.5 + (b - 1);
67 if (v > 0)
68 v = pow(((ii - 0.5) * c) + 0.5 + (b - 1), 1 / g) * 256;
69 else
70 v = 0;
71 if (v > 255)
72 v = 255;
73 else if (v < 0)
74 v = 0;
75 im->gmap[i] = (unsigned char)v;
76 }
77 g = ((double)im->bmod.gamma) / 256;
78 b = ((double)im->bmod.brightness) / 256;
79 c = ((double)im->bmod.contrast) / 256;
80 if (g < 0.01)
81 g = 0.01;
82 for (i = 0; i < 256; i++)
83 {
84 ii = ((double)im->bmap[i]) / 256;
85 v = ((ii - 0.5) * c) + 0.5 + (b - 1);
86 if (v > 0)
87 v = pow(((ii - 0.5) * c) + 0.5 + (b - 1), 1 / g) * 256;
88 else
89 v = 0;
90 if (v > 255)
91 v = 255;
92 else if (v < 0)
93 v = 0;
94 im->bmap[i] = (unsigned char)v;
95 }
96 gdirty_pixmaps(im);
97}
98
99gint
100gdk_imlib_load_file_to_pixmap(char *filename, GdkPixmap ** pmap, GdkBitmap ** mask)
101{
102 GdkImlibImage *im;
103
104 im = gdk_imlib_load_image(filename);
105 if (!im)
106 {
107 if (pmap)
108 *pmap = NULL;
109 if (mask)
110 *mask = NULL;
111 return 0;
112 }
113 if (!gdk_imlib_render(im, im->rgb_width, im->rgb_height))
114 {
115 gdk_imlib_destroy_image(im);
116 if (pmap)
117 *pmap = NULL;
118 if (mask)
119 *mask = NULL;
120 return 0;
121 }
122 if (pmap)
123 *pmap = gdk_imlib_move_image(im);
124 if (mask)
125 *mask = gdk_imlib_move_mask(im);
126 gdk_imlib_destroy_image(im);
127 return 1;
128}
129
130void
131gdk_imlib_set_image_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
132{
133 if (!im || !mod)
134 return;
135 im->mod.gamma = mod->gamma;
136 im->mod.brightness = mod->brightness;
137 im->mod.contrast = mod->contrast;
138 gcalc_map_tables(im);
139}
140
141void
142gdk_imlib_set_image_red_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
143{
144 if (!im || !mod)
145 return;
146 im->rmod.gamma = mod->gamma;
147 im->rmod.brightness = mod->brightness;
148 im->rmod.contrast = mod->contrast;
149 gcalc_map_tables(im);
150}
151
152void
153gdk_imlib_set_image_green_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
154{
155 if (!im || !mod)
156 return;
157 im->gmod.gamma = mod->gamma;
158 im->gmod.brightness = mod->brightness;
159 im->gmod.contrast = mod->contrast;
160 gcalc_map_tables(im);
161}
162
163void
164gdk_imlib_set_image_blue_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
165{
166 if (!im | !mod)
167 return;
168 im->bmod.gamma = mod->gamma;
169 im->bmod.brightness = mod->brightness;
170 im->bmod.contrast = mod->contrast;
171 gcalc_map_tables(im);
172}
173
174void
175gdk_imlib_get_image_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
176{
177 if (!im || !mod)
178 return;
179 mod->gamma = im->mod.gamma;
180 mod->brightness = im->mod.brightness;
181 mod->contrast = im->mod.contrast;
182 gcalc_map_tables(im);
183}
184
185void
186gdk_imlib_get_image_red_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
187{
188 if (!im || !mod)
189 return;
190 mod->gamma = im->rmod.gamma;
191 mod->brightness = im->rmod.brightness;
192 mod->contrast = im->rmod.contrast;
193}
194
195void
196gdk_imlib_get_image_green_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
197{
198 if (!im || !mod)
199 return;
200 mod->gamma = im->gmod.gamma;
201 mod->brightness = im->gmod.brightness;
202 mod->contrast = im->gmod.contrast;
203}
204
205void
206gdk_imlib_get_image_blue_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
207{
208 if (!im || !mod)
209 return;
210 mod->gamma = im->bmod.gamma;
211 mod->brightness = im->bmod.brightness;
212 mod->contrast = im->bmod.contrast;
213}
214
215void
216gdk_imlib_set_image_red_curve(GdkImlibImage * im, unsigned char *mod)
217{
218 int i;
219
220 if (!im || !mod)
221 return;
222 for (i = 0; i < 256; i++)
223 im->rmap[i] = mod[i];
224 gdirty_pixmaps(im);
225 im->mod.contrast = 257;
226}
227
228void
229gdk_imlib_set_image_green_curve(GdkImlibImage * im, unsigned char *mod)
230{
231 int i;
232
233 if (!im || !mod)
234 return;
235 for (i = 0; i < 256; i++)
236 im->gmap[i] = mod[i];
237 gdirty_pixmaps(im);
238 im->mod.contrast = 257;
239}
240
241void
242gdk_imlib_set_image_blue_curve(GdkImlibImage * im, unsigned char *mod)
243{
244 int i;
245
246 if (!im || !mod)
247 return;
248 for (i = 0; i < 256; i++)
249 im->bmap[i] = mod[i];
250 gdirty_pixmaps(im);
251 im->mod.contrast = 257;
252}
253
254void
255gdk_imlib_get_image_red_curve(GdkImlibImage * im, unsigned char *mod)
256{
257 int i;
258
259 if ((!im) || (!mod))
260 return;
261 for (i = 0; i < 256; i++)
262 mod[i] = im->rmap[i];
263}
264
265void
266gdk_imlib_get_image_green_curve(GdkImlibImage * im, unsigned char *mod)
267{
268 int i;
269
270 if (!im || !mod)
271 return;
272 for (i = 0; i < 256; i++)
273 mod[i] = im->gmap[i];
274}
275
276void
277gdk_imlib_get_image_blue_curve(GdkImlibImage * im, unsigned char *mod)
278{
279 int i;
280
281 if (!im || !mod)
282 return;
283 for (i = 0; i < 256; i++)
284 mod[i] = im->bmap[i];
285}
286
287void
288gdk_imlib_apply_modifiers_to_rgb(GdkImlibImage * im)
289{
290 int x, y;
291 unsigned char *ptr;
292
293 if (!im)
294 return;
295 ptr = im->rgb_data;
296 for (y = 0; y < im->rgb_height; y++)
297 {
298 for (x = 0; x < im->rgb_width; x++)
299 {
300 *ptr = im->rmap[*ptr];
301 ptr++;
302 *ptr = im->gmap[*ptr];
303 ptr++;
304 *ptr = im->bmap[*ptr];
305 ptr++;
306 }
307 }
308 im->mod.gamma = 256;
309 im->mod.brightness = 256;
310 im->mod.contrast = 256;
311 im->rmod.gamma = 256;
312 im->rmod.brightness = 256;
313 im->rmod.contrast = 256;
314 im->gmod.gamma = 256;
315 im->gmod.brightness = 256;
316 im->gmod.contrast = 256;
317 im->bmod.gamma = 256;
318 im->bmod.brightness = 256;
319 im->bmod.contrast = 256;
320 gcalc_map_tables(im);
321 gdirty_images(im);
322 gdirty_pixmaps(im);
323}
324
325void
326gdk_imlib_crop_image(GdkImlibImage * im, gint x, gint y, gint w, gint h)
327{
328 unsigned char *data;
329 int xx, yy, w3, w4;
330 unsigned char *ptr1, *ptr2;
331
332 if (!im)
333 return;
334 if (x < 0)
335 {
336 w += x;
337 x = 0;
338 }
339 if (y < 0)
340 {
341 h += y;
342 y = 0;
343 }
344 if (x >= im->rgb_width)
345 return;
346 if (y >= im->rgb_height)
347 return;
348 if (w <= 0)
349 return;
350 if (h <= 0)
351 return;
352 if (x + w > im->rgb_width)
353 w = im->rgb_width - x;
354 if (y + h > im->rgb_height)
355 h = im->rgb_height - y;
356 if (w <= 0)
357 return;
358 if (h <= 0)
359 return;
360
361 w3 = im->rgb_width * 3;
362 w4 = (im->rgb_width - w) * 3;
363 data = malloc(w * h * 3);
364 if (data == NULL)
365 return;
366 ptr1 = im->rgb_data + (y * w3) + (x * 3);
367 ptr2 = data;
368 for (yy = 0; yy < h; yy++)
369 {
370 for (xx = 0; xx < w; xx++)
371 {
372 *ptr2++ = *ptr1++;
373 *ptr2++ = *ptr1++;
374 *ptr2++ = *ptr1++;
375 }
376 ptr1 += w4;
377 }
378 free(im->rgb_data);
379 im->rgb_data = data;
380 if (im->border.left > x)
381 im->border.left = im->border.left - x;
382 else
383 im->border.left = 0;
384 if (im->border.top > y)
385 im->border.top = im->border.top - y;
386 else
387 im->border.top = 0;
388 if (im->rgb_width - im->border.right < x + w)
389 im->border.right = im->border.right - (im->rgb_width - (x + w));
390 else
391 im->border.right = 0;
392 if (im->rgb_height - im->border.bottom < y + h)
393 im->border.bottom = im->border.bottom - (im->rgb_height - (y + h));
394 else
395 im->border.bottom = 0;
396 im->rgb_width = w;
397 im->rgb_height = h;
398 gdirty_images(im);
399 gdirty_pixmaps(im);
400}
401
402void
403gdk_imlib_changed_image(GdkImlibImage * im)
404{
405 if (!im)
406 return;
407 gdirty_images(im);
408 gdirty_pixmaps(im);
409}
410
411void
412gdk_imlib_apply_image(GdkImlibImage * im, GdkWindow * p)
413{
414 GdkPixmap *pp, *mm;
415 int w, h;
416
417 if (!im || !p)
418 return;
419 gdk_window_get_size(p, &w, &h);
420 if (w <= 0 || h <= 0)
421 return;
422 gdk_imlib_render(im, w, h);
423 pp = gdk_imlib_move_image(im);
424 mm = gdk_imlib_move_mask(im);
425 gdk_window_set_back_pixmap(p, pp, 0);
426 if (mm)
427 gdk_window_shape_combine_mask(p, mm, 0, 0);
428 gdk_window_clear(p);
429 gdk_imlib_free_pixmap(pp);
430}
431
432void
433gdk_imlib_paste_image(GdkImlibImage * im, GdkWindow * p, gint x, gint y, gint w, gint h)
434{
435 GdkGC *gc;
436 GdkPixmap *pp, *mm;
437
438 if (!im || !p)
439 return;
440 if ((w <= 0) || (h <= 0))
441 return;
442 gc = gdk_gc_new(p);
443 gdk_imlib_render(im, w, h);
444 pp = gdk_imlib_move_image(im);
445 mm = gdk_imlib_move_mask(im);
446 if (mm)
447 {
448 gdk_gc_set_clip_mask(gc, mm);
449 gdk_gc_set_clip_origin(gc, x, y);
450 }
451 gdk_draw_pixmap(p, gc, pp, 0, 0, x, y, w, h);
452 gdk_imlib_free_pixmap(pp);
453 gdk_gc_destroy(gc);
454}
455
456void
457gdk_imlib_paste_image_border(GdkImlibImage * im, GdkWindow * p, gint x, gint y, gint w, gint h)
458{
459 GdkGC *gc;
460 GdkPixmap *pp, *mm;
461
462 if (!im)
463 return;
464
465 if (w <= 0 || h <= 0)
466 return;
467 gc = gdk_gc_new(p);
468 gdk_imlib_render(im, w, h);
469 pp = gdk_imlib_move_image(im);
470 mm = gdk_imlib_move_mask(im);
471 if (mm)
472 {
473 gdk_gc_set_clip_mask(gc, mm);
474 gdk_gc_set_clip_origin(gc, x, y);
475 }
476 if ((w <= (im->border.left + im->border.right)) ||
477 (h <= (im->border.top + im->border.bottom)))
478 gdk_draw_pixmap(p, gc, pp, 0, 0, x, y, w, h);
479 else
480 {
481 gdk_draw_pixmap(p, gc, pp, 0, 0, x, y, w, im->border.top);
482 gdk_draw_pixmap(p, gc, pp, 0, h - im->border.bottom,
483 x, y + (h - im->border.bottom),
484 w, im->border.bottom);
485 gdk_draw_pixmap(p, gc, pp, 0, im->border.top,
486 x, y + im->border.top,
487 im->border.left, h - (im->border.top + im->border.bottom));
488 gdk_draw_pixmap(p, gc, pp, w - im->border.right, h - im->border.bottom,
489 x + (w - im->border.right), y + (h - im->border.bottom),
490 im->border.right, h - (im->border.top + im->border.bottom));
491 }
492 gdk_imlib_free_pixmap(pp);
493 gdk_gc_destroy(gc);
494}
495
496void
497gdk_imlib_flip_image_horizontal(GdkImlibImage * im)
498{
499 unsigned char *ptr1, *ptr2, r, rr;
500 int x, y;
501 int w3;
502
503 if (!im)
504 return;
505 w3 = im->rgb_width * 3;
506 for (y = 0; y < im->rgb_height; y++)
507 {
508 ptr1 = im->rgb_data + (y * w3);
509 ptr2 = im->rgb_data + (y * w3) + w3 - 3;
510 for (x = 0; x < im->rgb_width >> 1; x++)
511 {
512 r = *ptr1;
513 rr = *ptr2;
514 *ptr2++ = r;
515 *ptr1++ = rr;
516
517 r = *ptr1;
518 rr = *ptr2;
519 *ptr2++ = r;
520 *ptr1++ = rr;
521
522 r = *ptr1;
523 rr = *ptr2;
524 *ptr2 = r;
525 *ptr1++ = rr;
526
527 ptr2 -= 5;
528 }
529 }
530 w3 = im->border.left;
531 im->border.left = im->border.right;
532 im->border.right = w3;
533 gdirty_images(im);
534 gdirty_pixmaps(im);
535}
536
537void
538gdk_imlib_flip_image_vertical(GdkImlibImage * im)
539{
540 unsigned char *ptr1, *ptr2, r, rr;
541 int x, y, yy;
542 int w3;
543
544 if (!im)
545 return;
546
547 w3 = im->rgb_width * 3;
548 for (yy = im->rgb_height - 1, y = 0; y < im->rgb_height >> 1; y++, yy--)
549 {
550 ptr1 = im->rgb_data + (y * w3);
551 ptr2 = im->rgb_data + (yy * w3);
552 for (x = 0; x < im->rgb_width; x++)
553 {
554 r = *ptr1;
555 rr = *ptr2;
556 *ptr2++ = r;
557 *ptr1++ = rr;
558 r = *ptr1;
559 rr = *ptr2;
560 *ptr2++ = r;
561 *ptr1++ = rr;
562 r = *ptr1;
563 rr = *ptr2;
564 *ptr2++ = r;
565 *ptr1++ = rr;
566 }
567 }
568 w3 = im->border.top;
569 im->border.top = im->border.bottom;
570 im->border.bottom = w3;
571 gdirty_images(im);
572 gdirty_pixmaps(im);
573}
574
575void
576gdk_imlib_rotate_image(GdkImlibImage * im, gint d)
577{
578 unsigned char *data;
579 int x, y, w3, w4;
580 unsigned char *ptr1, *ptr2;
581
582 if (!im)
583 return;
584 w3 = im->rgb_width * 3;
585 w4 = im->rgb_height * 3;
586
587 data = malloc(im->rgb_width * im->rgb_height * 3);
588 if (data == NULL)
589 return;
590
591 for (y = 0; y < im->rgb_height; y++)
592 {
593 ptr1 = im->rgb_data + (y * w3);
594 ptr2 = data + (y * 3);
595 for (x = 0; x < im->rgb_width; x++)
596 {
597 *ptr2++ = *ptr1++;
598 *ptr2++ = *ptr1++;
599 *ptr2 = *ptr1++;
600 ptr2 += w4 - 2;
601 }
602 }
603 free(im->rgb_data);
604 im->rgb_data = data;
605 w3 = im->rgb_width;
606 im->rgb_width = im->rgb_height;
607 im->rgb_height = w3;
608 w3 = im->border.top;
609 im->border.top = im->border.left;
610 im->border.left = w3;
611 w3 = im->border.bottom;
612 im->border.bottom = im->border.right;
613 im->border.right = w3;
614 gdirty_images(im);
615 gdirty_pixmaps(im);
616}
617
618GdkImlibImage *
619gdk_imlib_create_image_from_data(unsigned char *data, unsigned char *alpha, gint w, gint h)
620{
621 GdkImlibImage *im;
622 char s[128];
623
624 if (!data || w <= 0 || h <= 0)
625 return NULL;
626
627 im = malloc(sizeof(GdkImlibImage));
628 if (!im)
629 return NULL;
630
631 im->rgb_width = w;
632 im->rgb_height = h;
633 im->rgb_data = malloc(im->rgb_width * im->rgb_height * 3);
634 if (!im->rgb_data)
635 {
636 free(im);
637 return NULL;
638 }
639
640 memcpy(im->rgb_data, data, im->rgb_width * im->rgb_height * 3);
641/* im->alpha_data=alpha; */
642 im->alpha_data = NULL;
643 g_snprintf(s, sizeof(s), "creat_%x_%x", (int)time(NULL), (int)rand());
644 im->filename = malloc(strlen(s) + 1);
645 if (im->filename)
646 strcpy(im->filename, s);
647 im->width = 0;
648 im->height = 0;
649 im->shape_color.r = -1;
650 im->shape_color.g = -1;
651 im->shape_color.b = -1;
652 im->border.left = 0;
653 im->border.right = 0;
654 im->border.top = 0;
655 im->border.bottom = 0;
656 im->pixmap = NULL;
657 im->shape_mask = NULL;
658 im->cache = 1;
659 im->mod.gamma = id->mod.gamma;
660 im->mod.brightness = id->mod.brightness;
661 im->mod.contrast = id->mod.contrast;
662 im->rmod.gamma = id->rmod.gamma;
663 im->rmod.brightness = id->rmod.brightness;
664 im->rmod.contrast = id->rmod.contrast;
665 im->gmod.gamma = id->gmod.gamma;
666 im->gmod.brightness = id->gmod.brightness;
667 im->gmod.contrast = id->gmod.contrast;
668 im->bmod.gamma = id->bmod.gamma;
669 im->bmod.brightness = id->bmod.brightness;
670 im->bmod.contrast = id->bmod.contrast;
671 if (id->cache.on_image)
672 gadd_image(im, im->filename);
673 gcalc_map_tables(im);
674 return im;
675}
676
677GdkImlibImage *
678gdk_imlib_clone_image(GdkImlibImage * im)
679{
680 GdkImlibImage *im2;
681 char *s;
682
683 if (!im)
684 return NULL;
685 im2 = malloc(sizeof(GdkImlibImage));
686 if (!im2)
687 return NULL;
688 im2->rgb_width = im->rgb_width;
689 im2->rgb_height = im->rgb_height;
690 im2->rgb_data = malloc(im2->rgb_width * im2->rgb_height * 3);
691 if (!im2->rgb_data)
692 {
693 free(im2);
694 return NULL;
695 }
696
697 memcpy(im2->rgb_data, im->rgb_data, im2->rgb_width * im2->rgb_height * 3);
698 if (im->alpha_data)
699 {
700 im2->alpha_data = malloc(im2->rgb_width * im2->rgb_height);
701 if (!im2->alpha_data)
702 {
703 free(im2->rgb_data);
704 free(im2);
705 return NULL;
706 }
707 memcpy(im2->alpha_data, im->alpha_data, im2->rgb_width * im2->rgb_height);
708 }
709 else
710 im2->alpha_data = NULL;
711 s = malloc(strlen(im->filename) + 320);
712 if (s)
713 {
714 g_snprintf(s, sizeof(s), "%s_%x_%x", im->filename, (int)time(NULL), (int)rand());
715 im2->filename = malloc(strlen(s) + 1);
716 if (im2->filename)
717 strcpy(im2->filename, s);
718 free(s);
719 }
720 else
721 im2->filename = NULL;
722 im2->width = 0;
723 im2->height = 0;
724 im2->shape_color.r = im->shape_color.r;
725 im2->shape_color.g = im->shape_color.g;
726 im2->shape_color.b = im->shape_color.b;
727 im2->border.left = im->border.left;
728 im2->border.right = im->border.right;
729 im2->border.top = im->border.top;
730 im2->border.bottom = im->border.bottom;
731 im2->pixmap = NULL;
732 im2->shape_mask = NULL;
733 im2->cache = 1;
734 im2->mod.gamma = im->mod.gamma;
735 im2->mod.brightness = im->mod.brightness;
736 im2->mod.contrast = im->mod.contrast;
737 im2->rmod.gamma = im->rmod.gamma;
738 im2->rmod.brightness = im->rmod.brightness;
739 im2->rmod.contrast = im->rmod.contrast;
740 im2->gmod.gamma = im->gmod.gamma;
741 im2->gmod.brightness = im->gmod.brightness;
742 im2->gmod.contrast = im->gmod.contrast;
743 im2->bmod.gamma = im->bmod.gamma;
744 im2->bmod.brightness = im->bmod.brightness;
745 im2->bmod.contrast = im->bmod.contrast;
746 gcalc_map_tables(im2);
747 if (id->cache.on_image)
748 gadd_image(im2, im2->filename);
749 return im2;
750}
751
752GdkImlibImage *
753gdk_imlib_clone_scaled_image(GdkImlibImage * im, int w, int h)
754{
755 GdkImlibImage *im2;
756 char *s;
757
758 if (!im || w <= 0 || h <= 0)
759 return NULL;
760
761 im2 = malloc(sizeof(GdkImlibImage));
762 if (!im2)
763 return NULL;
764 im2->rgb_width = w;
765 im2->rgb_height = h;
766 im2->rgb_data = malloc(w * h * 3);
767 if (!im2->rgb_data)
768 {
769 free(im2);
770 return NULL;
771 }
772 {
773 int x, y, *xarray;
774 unsigned char **yarray, *ptr, *ptr2, *ptr22;
775 int l, r, m, pos, inc, w3;
776
777 xarray = malloc(sizeof(int) * w);
778
779 if (!xarray)
780 {
781 fprintf(stderr, "ERROR: Cannot allocate X co-ord buffer\n");
782 free(im2->rgb_data);
783 free(im2);
784 return NULL;
785 }
786 yarray = malloc(sizeof(unsigned char *) * h);
787
788 if (!yarray)
789 {
790 fprintf(stderr, "ERROR: Cannot allocate Y co-ord buffer\n");
791 free(xarray);
792 free(im2->rgb_data);
793 free(im2);
794 return NULL;
795 }
796 ptr22 = im->rgb_data;
797 w3 = im->rgb_width * 3;
798 inc = 0;
799 if (w < im->border.left + im->border.right)
800 {
801 l = w >> 1;
802 r = w - l;
803 m = 0;
804 }
805 else
806 {
807 l = im->border.left;
808 r = im->border.right;
809 m = w - l - r;
810 }
811 if (m > 0)
812 inc = ((im->rgb_width - im->border.left - im->border.right) << 16) / m;
813 pos = 0;
814 if (l)
815 {
816 for (x = 0; x < l; x++)
817 {
818 xarray[x] = (pos >> 16) + (pos >> 16) + (pos >> 16);
819 pos += 0x10000;
820 }
821 }
822 if (m)
823 {
824 for (x = l; x < l + m; x++)
825 {
826 xarray[x] = (pos >> 16) + (pos >> 16) + (pos >> 16);
827 pos += inc;
828 }
829 }
830 pos = (im->rgb_width - r) << 16;
831 for (x = w - r; x < w; x++)
832 {
833 xarray[x] = (pos >> 16) + (pos >> 16) + (pos >> 16);
834 pos += 0x10000;
835 }
836
837 if (h < im->border.top + im->border.bottom)
838 {
839 l = h >> 1;
840 r = h - l;
841 m = 0;
842 }
843 else
844 {
845 l = im->border.top;
846 r = im->border.bottom;
847 m = h - l - r;
848 }
849 if (m > 0)
850 inc = ((im->rgb_height - im->border.top - im->border.bottom) << 16) / m;
851 pos = 0;
852 for (x = 0; x < l; x++)
853 {
854 yarray[x] = ptr22 + ((pos >> 16) * w3);
855 pos += 0x10000;
856 }
857 if (m)
858 {
859 for (x = l; x < l + m; x++)
860 {
861 yarray[x] = ptr22 + ((pos >> 16) * w3);
862 pos += inc;
863 }
864 }
865 pos = (im->rgb_height - r) << 16;
866 for (x = h - r; x < h; x++)
867 {
868 yarray[x] = ptr22 + ((pos >> 16) * w3);
869 pos += 0x10000;
870 }
871
872 ptr = im2->rgb_data;
873 for (y = 0; y < h; y++)
874 {
875 for (x = 0; x < w; x++)
876 {
877 ptr2 = yarray[y] + xarray[x];
878 *ptr++ = (int)*ptr2++;
879 *ptr++ = (int)*ptr2++;
880 *ptr++ = (int)*ptr2;
881 }
882 }
883 }
884 if (im->alpha_data)
885 {
886 im2->alpha_data = NULL;
887 /* yet to be filled in */
888 }
889 else
890 im2->alpha_data = NULL;
891
892 s = malloc(strlen(im->filename) + 320);
893 if (s)
894 {
895 g_snprintf(s, sizeof(s), "%s_%x_%x_%x_%x", im->filename, (int)time(NULL), w, h, (int)rand());
896 im2->filename = malloc(strlen(s) + 1);
897 if (im2->filename)
898 strcpy(im2->filename, s);
899 free(s);
900 }
901 else
902 im2->filename = NULL;
903 im2->width = 0;
904 im2->height = 0;
905 im2->shape_color.r = im->shape_color.r;
906 im2->shape_color.g = im->shape_color.g;
907 im2->shape_color.b = im->shape_color.b;
908 im2->border.left = im->border.left;
909 im2->border.right = im->border.right;
910 im2->border.top = im->border.top;
911 im2->border.bottom = im->border.bottom;
912 im2->pixmap = NULL;
913 im2->shape_mask = NULL;
914 im2->cache = 1;
915 im2->mod.gamma = im->mod.gamma;
916 im2->mod.brightness = im->mod.brightness;
917 im2->mod.contrast = im->mod.contrast;
918 im2->rmod.gamma = im->rmod.gamma;
919 im2->rmod.brightness = im->rmod.brightness;
920 im2->rmod.contrast = im->rmod.contrast;
921 im2->gmod.gamma = im->gmod.gamma;
922 im2->gmod.brightness = im->gmod.brightness;
923 im2->gmod.contrast = im->gmod.contrast;
924 im2->bmod.gamma = im->bmod.gamma;
925 im2->bmod.brightness = im->bmod.brightness;
926 im2->bmod.contrast = im->bmod.contrast;
927 gcalc_map_tables(im2);
928 if (id->cache.on_image)
929 gadd_image(im2, im2->filename);
930 return im2;
931}
932
933GdkImlibImage *
934gdk_imlib_create_image_from_xpm_data(char **data)
935{
936 GdkImlibImage *im;
937 unsigned char *ptr;
bd7d06f2 938 int /* pc, */ c, i, j, k, ncolors, cpp, comment, transp, quote,
c801d85f
KB
939 context, len, count, done;
940 int w, h;
941 char *line, s[65536], tok[65536], col[65536];
942 XColor xcol;
943 struct _cmap
944 {
945 char str[8];
946 char transp;
947 int r, g, b;
948 }
949 *cmap;
bd7d06f2 950
c801d85f
KB
951 int lookup[128][128];
952
bd7d06f2
RR
953 cmap = NULL;
954 j = 0;
c801d85f
KB
955 if (!data)
956 return NULL;
957 im = malloc(sizeof(GdkImlibImage));
958 if (!im)
959 return NULL;
960 count = 0;
961 transp = 0;
962 done = 0;
963
964 c = ' ';
965 comment = 0;
966 quote = 0;
967 context = 0;
968 ptr = NULL;
969
970 while (!done)
971 {
972 line = data[count++];
973 if (context == 0)
974 {
975 /* Header */
976 sscanf(line, "%i %i %i %i", &w, &h, &ncolors, &cpp);
977 if (cpp > 7)
978 {
979 fprintf(stderr, "gdk_imlib ERROR: XPM data with characters per pixel > 7 not supported\n");
980 free(im);
981 return NULL;
982 }
983 if (w > 32767)
984 {
985 fprintf(stderr, "gdk_imlib ERROR: Image width > 32767 pixels for data\n");
986 free(im);
987 return NULL;
988 }
989 if (h > 32767)
990 {
991 fprintf(stderr, "gdk_imlib ERROR: Image height > 32767 pixels for data\n");
992 free(im);
993 return NULL;
994 }
995 cmap = malloc(sizeof(struct _cmap) * ncolors);
996
997 if (!cmap)
998 {
999 free(im);
1000 return NULL;
1001 }
1002 im->rgb_width = w;
1003 im->rgb_height = h;
1004 im->rgb_data = malloc(im->rgb_width * im->rgb_height * 3);
1005 if (!im->rgb_data)
1006 {
1007 free(cmap);
1008 free(im);
1009 return NULL;
1010 }
1011 im->alpha_data = NULL;
1012 g_snprintf(s, sizeof(s), "creat_%x_%x", (int)time(NULL), (int)rand());
1013 im->filename = malloc(strlen(s) + 1);
1014 if (im->filename)
1015 strcpy(im->filename, s);
1016 im->width = 0;
1017 im->height = 0;
1018 im->border.left = 0;
1019 im->border.right = 0;
1020 im->border.top = 0;
1021 im->border.bottom = 0;
1022 im->pixmap = NULL;
1023 im->shape_mask = NULL;
1024 im->cache = 1;
1025 im->mod.gamma = id->mod.gamma;
1026 im->mod.brightness = id->mod.brightness;
1027 im->mod.contrast = id->mod.contrast;
1028 im->rmod.gamma = id->rmod.gamma;
1029 im->rmod.brightness = id->rmod.brightness;
1030 im->rmod.contrast = id->rmod.contrast;
1031 im->gmod.gamma = id->gmod.gamma;
1032 im->gmod.brightness = id->gmod.brightness;
1033 im->gmod.contrast = id->gmod.contrast;
1034 im->bmod.gamma = id->bmod.gamma;
1035 im->bmod.brightness = id->bmod.brightness;
1036 im->bmod.contrast = id->bmod.contrast;
1037 ptr = im->rgb_data;
1038 j = 0;
1039 context++;
1040 }
1041 else if (context == 1)
1042 {
1043 int colptr;
1044
1045 /* Color Table */
1046 if (j < ncolors)
1047 {
1048 tok[0] = 0;
1049 col[0] = 0;
1050 s[0] = 0;
1051 colptr = 0;
1052 len = strlen(line);
1053 strncpy(cmap[j].str, line, cpp);
1054 cmap[j].str[cpp] = 0;
1055 cmap[j].r = -1;
1056 cmap[j].transp = 0;
1057 for (k = cpp; k < len; k++)
1058 {
1059 if (line[k] != ' ')
1060 {
1061 sscanf(&line[k], "%65536s", s);
1062 k += strlen(s);
1063 if ((!strcmp(s, "m")) || (!strcmp(s, "s")) ||
1064 (!strcmp(s, "g4")) || (!strcmp(s, "g")) ||
1065 (!strcmp(s, "c")) || (k >= len))
1066 {
1067 if (k >= len)
1068 {
1069 int ls;
1070
1071 ls = strlen(s);
1072
1073 if (col[0] && colptr < sizeof(col))
1074 {
1075 strcpy(col + colptr, " ");
1076 colptr++;
1077 }
1078 if (colptr + ls <= sizeof(col))
1079 {
1080 strcpy(col + colptr, s);
1081 colptr += ls;
1082 }
1083
1084 }
1085 if (col[0])
1086 {
1087 if (!strcasecmp(col, "none"))
1088 {
1089 transp = 1;
1090 cmap[j].transp = 1;
1091 }
1092 else
1093 {
1094 if ((cmap[j].r < 0) ||
1095 (!strcmp(tok, "c")))
1096 {
1097 XParseColor(id->x.disp,
1098 id->x.root_cmap,
1099 col, &xcol);
1100 cmap[j].r = xcol.red >> 8;
1101 cmap[j].g = xcol.green >> 8;
1102 cmap[j].b = xcol.blue >> 8;
1103 if ((cmap[j].r == 255) &&
1104 (cmap[j].g == 0) &&
1105 (cmap[j].b == 255))
1106 cmap[j].r = 254;
1107 }
1108 }
1109 }
1110 if (strlen(s) < sizeof(tok))
1111 strcpy(tok, s);
1112 col[0] = 0;
1113 }
1114 else
1115 {
1116 int ls;
1117
1118 ls = strlen(s);
1119
1120 if (col[0] && colptr < sizeof(col))
1121 {
1122 strcpy(col + colptr, " ");
1123 colptr++;
1124 }
1125 if (ls + colptr < sizeof(col))
1126 {
1127 strcpy(col + colptr, s);
1128 colptr += ls;
1129 }
1130 }
1131 }
1132 }
1133 }
1134 j++;
1135 if (j >= ncolors)
1136 {
1137 if (cpp == 1)
1138 for (i = 0; i < ncolors; i++)
bd7d06f2 1139 lookup[(int)cmap[i].str[0]][(int)cmap[i].str[1]] = i;
c801d85f
KB
1140 if (cpp == 2)
1141 for (i = 0; i < ncolors; i++)
bd7d06f2 1142 lookup[(int)cmap[i].str[0]][(int)cmap[i].str[1]] = i;
c801d85f
KB
1143 context++;
1144 }
1145 }
1146 else
1147 {
1148 /* Image Data */
1149 i = 0;
1150 if (cpp == 0)
1151 {
1152 }
1153 else if (cpp == 1)
1154 {
1155 if (transp)
1156 {
1157 for (i = 0; ((i < 65536) && (line[i])); i++)
1158 {
1159 col[0] = line[i];
bd7d06f2 1160 if (cmap[lookup[(int)col[0]][0]].transp)
c801d85f
KB
1161 {
1162 *ptr++ = 255;
1163 *ptr++ = 0;
1164 *ptr++ = 255;
1165 }
1166 else
1167 {
bd7d06f2
RR
1168 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].r;
1169 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].g;
1170 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].b;
c801d85f
KB
1171 }
1172 }
1173 }
1174 else
1175 {
1176 for (i = 0; ((i < 65536) && (line[i])); i++)
1177 {
1178 col[0] = line[i];
bd7d06f2
RR
1179 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].r;
1180 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].g;
1181 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].b;
c801d85f
KB
1182 }
1183 }
1184 }
1185 else if (cpp == 2)
1186 {
1187 if (transp)
1188 {
1189 for (i = 0; ((i < 65536) && (line[i])); i++)
1190 {
1191 col[0] = line[i++];
1192 col[1] = line[i];
bd7d06f2 1193 if (cmap[lookup[(int)col[0]][(int)col[1]]].transp)
c801d85f
KB
1194 {
1195 *ptr++ = 255;
1196 *ptr++ = 0;
1197 *ptr++ = 255;
1198 }
1199 else
1200 {
bd7d06f2
RR
1201 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].r;
1202 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].g;
1203 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].b;
c801d85f
KB
1204 }
1205 }
1206 }
1207 else
1208 {
1209 for (i = 0; ((i < 65536) && (line[i])); i++)
1210 {
1211 col[0] = line[i++];
1212 col[1] = line[i];
bd7d06f2
RR
1213 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].r;
1214 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].g;
1215 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].b;
c801d85f
KB
1216 }
1217 }
1218 }
1219 else
1220 {
1221 if (transp)
1222 {
1223 for (i = 0; ((i < 65536) && (line[i])); i++)
1224 {
1225 for (j = 0; j < cpp; j++, i++)
1226 {
1227 col[j] = line[i];
1228 }
1229 col[j] = 0;
1230 i--;
1231 for (j = 0; j < ncolors; j++)
1232 {
1233 if (!strcmp(col, cmap[j].str))
1234 {
1235 if (cmap[j].transp)
1236 {
1237 *ptr++ = 255;
1238 *ptr++ = 0;
1239 *ptr++ = 255;
1240 }
1241 else
1242 {
1243 *ptr++ = (unsigned char)cmap[j].r;
1244 *ptr++ = (unsigned char)cmap[j].g;
1245 *ptr++ = (unsigned char)cmap[j].b;
1246 }
1247 j = ncolors;
1248 }
1249 }
1250 }
1251 }
1252 else
1253 {
1254 for (i = 0; ((i < 65536) && (line[i])); i++)
1255 {
1256 for (j = 0; j < cpp; j++, i++)
1257 {
1258 col[j] = line[i];
1259 }
1260 col[j] = 0;
1261 i--;
1262 for (j = 0; j < ncolors; j++)
1263 {
1264 if (!strcmp(col, cmap[j].str))
1265 {
1266 *ptr++ = (unsigned char)cmap[j].r;
1267 *ptr++ = (unsigned char)cmap[j].g;
1268 *ptr++ = (unsigned char)cmap[j].b;
1269 j = ncolors;
1270 }
1271 }
1272 }
1273 }
1274 }
1275 }
1276 if ((ptr) && ((ptr - im->rgb_data) >= w * h * 3))
1277 done = 1;
1278 }
1279 if (!transp)
1280 {
1281 im->shape_color.r = -1;
1282 im->shape_color.g = -1;
1283 im->shape_color.b = -1;
1284 }
1285 else
1286 {
1287 im->shape_color.r = 255;
1288 im->shape_color.g = 0;
1289 im->shape_color.b = 255;
1290 }
1291 if (id->cache.on_image)
1292 gadd_image(im, im->filename);
1293 gcalc_map_tables(im);
1294 free(cmap);
1295 return im;
1296}
1297
1298gint
1299gdk_imlib_data_to_pixmap(char **data, GdkPixmap ** pmap, GdkBitmap ** mask)
1300{
1301 GdkImlibImage *im;
1302
1303 im = gdk_imlib_create_image_from_xpm_data(data);
1304 if (!im)
1305 {
1306 if (pmap)
1307 *pmap = NULL;
1308 if (mask)
1309 *mask = NULL;
1310 return 0;
1311 }
1312 if (!gdk_imlib_render(im, im->rgb_width, im->rgb_height))
1313 {
1314 gdk_imlib_destroy_image(im);
1315 if (pmap)
1316 *pmap = NULL;
1317 if (mask)
1318 *mask = NULL;
1319 return 0;
1320 }
1321 if (pmap)
1322 *pmap = gdk_imlib_move_image(im);
1323 if (mask)
1324 *mask = gdk_imlib_move_mask(im);
1325 gdk_imlib_kill_image(im);
1326 return 1;
1327}
1328
1329#include <signal.h>
1330#include <sys/wait.h>
1331
1332/*
1333 * Helper library
1334 */
1335
1336static int hpid;
1337void *oldpiper; /* actually sighandler_t but BSD uses sig_t. */
1338
1339FILE *
1340open_helper(const char *instring, const char *fn, const char *mode)
1341{
1342 char buf[256]; /* This is safe since our input strings
1343
1344 *
1345 * * are bounded */
1346 static char *vec[16];
1347 char *p = strdup(instring);
1348 char *pp;
1349 char *ep;
1350 int vn = 0;
1351 int pid;
1352 FILE *fp = NULL;
1353 char *ofil = NULL;
1354 int ofd = -1;
1355
1356 int pfd[2];
1357
1358 if (p == NULL)
1359 return NULL;
1360
1361 if (strncmp(instring, "%Q", 2) == 0)
1362 {
1363 /*
1364 * Generate a quanting pipeline
1365 */
1366 fprintf(stderr, "Not currently supported: install ImageMagic.\n");
1367 return NULL;
1368 }
1369 /*
1370 * Ok split the instring on spaces and translate
1371 * %C %P %F and %s
1372 *
1373 * FIXME: We need to handle a format string that begins
1374 * %Q to indicate an 8bit quant in the pipeline first.
1375 */
1376
1377 pp = p;
1378
1379 while (vn < 15)
1380 {
1381 while (*pp && isspace(*pp))
1382 pp++;
1383 ep = pp;
1384 while (*ep && !isspace(*ep))
1385 ep++;
1386 if (*pp == 0)
1387 break;
1388 /* pp->ep is now the input string block */
1389 if (*ep)
1390 *ep++ = 0;
1391
1392 if (strcmp(pp, "%s") == 0)
1393 vec[vn] = strdup(fn);
1394 else if (strncmp(pp, "%P/", 3) == 0)
1395 {
1396 strcpy(buf, NETPBM_PATH);
1397 strcat(buf, pp + 2);
1398 if ((vec[vn] = strdup(buf)) == NULL)
1399 break;
1400 }
1401 else if (strncmp(pp, "%J", 3) == 0)
1402 {
1403 if ((vec[vn] = strdup(DJPEG_PROG)) == NULL)
1404 break;
1405 }
1406 else if (strncmp(pp, "%H", 3) == 0)
1407 {
1408 if ((vec[vn] = strdup(CJPEG_PROG)) == NULL)
1409 break;
1410 }
1411 else if (strncmp(pp, "%C/", 3) == 0)
1412 {
1413 strcpy(buf, CONVERT_PATH);
1414 strcat(buf, pp + 2);
1415 if ((vec[vn] = strdup(buf)) == NULL)
1416 break;
1417 }
1418 else if (strncmp(pp, ">%s", 3) == 0)
1419 {
1420 ofil = pp;
1421 vn++;
1422 pp = ep;
1423 continue;
1424 }
1425 else
1426 {
1427 if ((vec[vn] = strdup(pp)) == NULL)
1428 break;
1429 }
1430 vn++;
1431 pp = ep;
1432 }
1433
1434 vec[vn] = NULL;
1435
1436 if (pipe(pfd) == -1)
1437 goto oops;
1438
1439 if (*mode == 'r')
1440 {
1441 fp = fdopen(pfd[0], "r");
1442 if (fp == NULL)
1443 goto oops;
1444 }
1445 else if (*mode == 'w')
1446 {
1447 fp = fdopen(pfd[1], "w");
1448 if (fp == NULL)
1449 goto oops;
1450 }
1451 else
1452 goto oops;
1453
1454 if (ofil != NULL)
1455 if ((ofd = open(ofil, O_WRONLY | O_TRUNC | O_CREAT)) == -1)
1456 goto oops;
1457
1458 switch (pid = fork())
1459 {
1460 case -1:
1461 break;
1462 case 0:
1463 signal(SIGPIPE, SIG_DFL);
1464 if (*mode == 'r')
1465 dup2(pfd[1], 1);
1466 if (*mode == 'w')
1467 {
1468 dup2(pfd[0], 0);
1469 if (ofd != -1)
1470 {
1471 dup2(ofd, 1);
1472 close(1);
1473 }
1474 }
1475 close(pfd[0]);
1476 close(pfd[1]);
1477 execv(vec[0], vec);
1478 perror(vec[0]);
1479 /*
1480 * This MUST be _exit or we will hit the SIGPIPE
1481 * handler in ways we dont want. We want our parent
1482 * to flush the inherited file buffers not us.
1483 */
1484 _exit(1);
1485 default:
1486 hpid = pid;
1487
1488 if (ofd != -1)
1489 close(ofd);
1490 if (*mode == 'r')
1491 close(pfd[1]);
1492 else
1493 close(pfd[0]);
1494 }
1495 for (vn = 0; vn < 16; vn++)
1496 if (vec[vn])
1497 free(vec[vn]);
1498 oldpiper = signal(SIGPIPE, SIG_IGN);
1499 return fp;
1500
1501 oops:
1502 if (ofd != -1)
1503 close(ofd);
1504 if (fp)
1505 fclose(fp);
1506 for (vn = 0; vn < 16; vn++)
1507 if (vec[vn])
1508 free(vec[vn]);
1509 return NULL;
1510}
1511
1512int
1513close_helper(FILE * fp)
1514{
1515 int info;
1516
1517 fclose(fp);
1518 signal(SIGPIPE, oldpiper);
1519 waitpid(hpid, &info, 0);
1520 return WEXITSTATUS(info);
1521}