ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/background.C
(Generate patch)

Comparing rxvt-unicode/src/background.C (file contents):
Revision 1.201 by sf-exg, Sat Feb 4 21:47:06 2012 UTC vs.
Revision 1.210 by sf-exg, Sat May 12 09:43:06 2012 UTC

3 *----------------------------------------------------------------------* 3 *----------------------------------------------------------------------*
4 * 4 *
5 * All portions of code are copyright by their respective author/s. 5 * All portions of code are copyright by their respective author/s.
6 * Copyright (c) 2005-2008 Marc Lehmann <schmorp@schmorp.de> 6 * Copyright (c) 2005-2008 Marc Lehmann <schmorp@schmorp.de>
7 * Copyright (c) 2007 Sasha Vasko <sasha@aftercode.net> 7 * Copyright (c) 2007 Sasha Vasko <sasha@aftercode.net>
8 * Copyright (c) 2010 Emanuele Giaquinta <e.giaquinta@glauco.it> 8 * Copyright (c) 2010-2012 Emanuele Giaquinta <e.giaquinta@glauco.it>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or 12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. 13 * (at your option) any later version.
123 123
124# ifdef BG_IMAGE_FROM_FILE 124# ifdef BG_IMAGE_FROM_FILE
125static inline int 125static inline int
126make_align_position (int align, int window_size, int image_size) 126make_align_position (int align, int window_size, int image_size)
127{ 127{
128 int diff = window_size - image_size;
129 int smaller = min (image_size, window_size);
130
131 if (align >= 0 && align <= 100) 128 if (align >= 0 && align <= 100)
132 return diff * align / 100; 129 return lerp (0, window_size - image_size, align);
133 else if (align > 100 && align <= 200) 130 else if (align > 100)
134 return (align - 100) * smaller / 100 + window_size - smaller; 131 return lerp (window_size - image_size, window_size, align - 100);
135 else if (align >= -100 && align < 0) 132 else
136 return (align + 100) * smaller / 100 - image_size; 133 return lerp (-image_size, 0, align + 100);
137 return 0;
138} 134}
139 135
140static inline int 136static inline int
141make_clip_rectangle (int pos, int size, int target_size, int &dst_pos, int &dst_size) 137make_clip_rectangle (int pos, int size, int target_size, int &dst_pos, int &dst_size)
142{ 138{
334 { 330 {
335 x = make_align_position (h_align, target_width, w); 331 x = make_align_position (h_align, target_width, w);
336 y = make_align_position (v_align, target_height, h); 332 y = make_align_position (v_align, target_height, h);
337 } 333 }
338 334
339 bg_flags &= ~BG_IS_SIZE_SENSITIVE;
340 if (!(bg_flags & BG_TILE) 335 if (!(bg_flags & BG_TILE)
341 || h_scale || v_scale 336 || h_scale || v_scale
342 || (!(bg_flags & BG_ROOT_ALIGN) && (h_align || v_align)) 337 || (!(bg_flags & BG_ROOT_ALIGN) && (h_align || v_align))
343 || w > target_width || h > target_height) 338 || image_width > target_width || image_height > target_height)
344 bg_flags |= BG_IS_SIZE_SENSITIVE; 339 bg_flags |= BG_IS_SIZE_SENSITIVE;
340 else
341 bg_flags &= ~BG_IS_SIZE_SENSITIVE;
345} 342}
346 343
347# ifdef HAVE_PIXBUF 344# ifdef HAVE_PIXBUF
348bool 345bool
349rxvt_term::pixbuf_to_pixmap (GdkPixbuf *pixbuf, Pixmap pixmap, GC gc, 346rxvt_term::pixbuf_to_pixmap (GdkPixbuf *pixbuf, Pixmap pixmap, GC gc,
350 int src_x, int src_y, int dst_x, int dst_y, 347 int src_x, int src_y, int dst_x, int dst_y,
351 unsigned int width, unsigned int height) 348 unsigned int width, unsigned int height)
352{ 349{
353 XImage *ximage; 350 XImage *ximage;
354 char *data, *line; 351 char *line;
355 int bytes_per_pixel;
356 int width_r, width_g, width_b; 352 int width_r, width_g, width_b, width_a;
357 int sh_r, sh_g, sh_b; 353 int sh_r, sh_g, sh_b, sh_a;
354 uint32_t alpha_mask;
358 int rowstride; 355 int rowstride;
359 int channels; 356 int channels;
360 unsigned char *row; 357 unsigned char *row;
361 358
362 if (visual->c_class != TrueColor) 359 if (visual->c_class != TrueColor)
363 return false; 360 return false;
364 361
365 if (depth == 24 || depth == 32) 362#if XRENDER
366 bytes_per_pixel = 4; 363 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
367 else if (depth == 15 || depth == 16) 364 if (format)
368 bytes_per_pixel = 2; 365 alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha;
369 else 366 else
370 return false; 367#endif
368 alpha_mask = 0;
371 369
372 width_r = ecb_popcount32 (visual->red_mask); 370 width_r = ecb_popcount32 (visual->red_mask);
373 width_g = ecb_popcount32 (visual->green_mask); 371 width_g = ecb_popcount32 (visual->green_mask);
374 width_b = ecb_popcount32 (visual->blue_mask); 372 width_b = ecb_popcount32 (visual->blue_mask);
373 width_a = ecb_popcount32 (alpha_mask);
375 374
376 if (width_r > 8 || width_g > 8 || width_b > 8) 375 if (width_r > 8 || width_g > 8 || width_b > 8 || width_a > 8)
377 return false; 376 return false;
378 377
379 sh_r = ecb_ctz32 (visual->red_mask); 378 sh_r = ecb_ctz32 (visual->red_mask);
380 sh_g = ecb_ctz32 (visual->green_mask); 379 sh_g = ecb_ctz32 (visual->green_mask);
381 sh_b = ecb_ctz32 (visual->blue_mask); 380 sh_b = ecb_ctz32 (visual->blue_mask);
381 sh_a = ecb_ctz32 (alpha_mask);
382 382
383 if (width > INT_MAX / height / bytes_per_pixel) 383 if (width > 32767 || height > 32767)
384 return false; 384 return false;
385 385
386 data = (char *)malloc (width * height * bytes_per_pixel); 386 ximage = XCreateImage (dpy, visual, depth, ZPixmap, 0, 0,
387 if (!data) 387 width, height, 32, 0);
388 if (!ximage)
388 return false; 389 return false;
389 390
390 ximage = XCreateImage (dpy, visual, depth, ZPixmap, 0, data, 391 if (height > INT_MAX / ximage->bytes_per_line
391 width, height, bytes_per_pixel * 8, 0); 392 || !(ximage->data = (char *)malloc (height * ximage->bytes_per_line)))
392 if (!ximage)
393 { 393 {
394 free (data); 394 XDestroyImage (ximage);
395 return false; 395 return false;
396 } 396 }
397 397
398 ximage->byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 398 ximage->byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
399 399
400 rowstride = gdk_pixbuf_get_rowstride (pixbuf); 400 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
401 channels = gdk_pixbuf_get_n_channels (pixbuf); 401 channels = gdk_pixbuf_get_n_channels (pixbuf);
402 row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels; 402 row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels;
403 line = data; 403 line = ximage->data;
404
405 rgba c (0, 0, 0);
406
407 if (channels == 4 && alpha_mask == 0)
408 {
409 pix_colors[Color_bg].get (c);
410 c.r >>= 8;
411 c.g >>= 8;
412 c.b >>= 8;
413 }
404 414
405 for (int y = 0; y < height; y++) 415 for (int y = 0; y < height; y++)
406 { 416 {
407 for (int x = 0; x < width; x++) 417 for (int x = 0; x < width; x++)
408 { 418 {
409 unsigned char *pixel = row + x * channels; 419 unsigned char *pixel = row + x * channels;
410 uint32_t value; 420 uint32_t value;
421 unsigned char r, g, b, a;
411 422
423 if (channels == 4)
424 {
425 a = pixel[3];
426 r = (pixel[0] * a + c.r * (0xff - a)) / 0xff;
427 g = (pixel[1] * a + c.g * (0xff - a)) / 0xff;
428 b = (pixel[2] * a + c.b * (0xff - a)) / 0xff;
429 }
430 else
431 {
432 a = 0xff;
433 r = pixel[0];
434 g = pixel[1];
435 b = pixel[2];
436 }
437
412 value = ((pixel[0] >> (8 - width_r)) << sh_r) 438 value = ((r >> (8 - width_r)) << sh_r)
413 | ((pixel[1] >> (8 - width_g)) << sh_g) 439 | ((g >> (8 - width_g)) << sh_g)
414 | ((pixel[2] >> (8 - width_b)) << sh_b); 440 | ((b >> (8 - width_b)) << sh_b)
441 | ((a >> (8 - width_a)) << sh_a);
415 442
416 if (bytes_per_pixel == 4) 443 if (ximage->bits_per_pixel == 32)
417 ((uint32_t *)line)[x] = value; 444 ((uint32_t *)line)[x] = value;
418 else 445 else
419 ((uint16_t *)line)[x] = value; 446 XPutPixel (ximage, x, y, value);
420 } 447 }
421 448
422 row += rowstride; 449 row += rowstride;
423 line += ximage->bytes_per_line; 450 line += ximage->bytes_per_line;
424 } 451 }
427 XDestroyImage (ximage); 454 XDestroyImage (ximage);
428 return true; 455 return true;
429} 456}
430 457
431bool 458bool
432rxvt_term::render_image (unsigned long tr_flags) 459rxvt_term::render_image (bool transparent)
433{ 460{
434 if (!pixbuf) 461 if (!pixbuf)
435 return false; 462 return false;
436 463
437 if (tr_flags 464 if (transparent
438 && !(bg_flags & BG_HAS_RENDER)) 465 && !(bg_flags & BG_HAS_RENDER))
439 return false; 466 return false;
440 467
441 GdkPixbuf *result; 468 GdkPixbuf *result;
442 469
482 Pixmap root_pmap; 509 Pixmap root_pmap;
483 510
484 image_width = gdk_pixbuf_get_width (result); 511 image_width = gdk_pixbuf_get_width (result);
485 image_height = gdk_pixbuf_get_height (result); 512 image_height = gdk_pixbuf_get_height (result);
486 513
487 if (tr_flags) 514 if (transparent)
488 { 515 {
489 root_pmap = bg_pixmap; 516 root_pmap = bg_pixmap;
490 bg_pixmap = None; 517 bg_pixmap = None;
491 } 518 }
492 else 519 else
550 dst_x, dst_y, 577 dst_x, dst_y,
551 dst_width, dst_height); 578 dst_width, dst_height);
552 } 579 }
553 580
554#if XRENDER 581#if XRENDER
555 if (tr_flags) 582 if (transparent)
556 { 583 {
557 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 584 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
558 585
559 Picture src = XRenderCreatePicture (dpy, root_pmap, format, 0, 0); 586 Picture src = XRenderCreatePicture (dpy, root_pmap, format, 0, 0);
560 587
584 } 611 }
585 612
586 if (result != pixbuf) 613 if (result != pixbuf)
587 g_object_unref (result); 614 g_object_unref (result);
588 615
589 if (tr_flags) 616 if (transparent)
590 XFreePixmap (dpy, root_pmap); 617 XFreePixmap (dpy, root_pmap);
591 618
592 return ret; 619 return ret;
593} 620}
594# endif /* HAVE_PIXBUF */ 621# endif /* HAVE_PIXBUF */
675 { 702 {
676 changed = true; 703 changed = true;
677 v_blurRadius = vr; 704 v_blurRadius = vr;
678 } 705 }
679 706
680 if (h_blurRadius == 0 || v_blurRadius == 0) 707 if (h_blurRadius && v_blurRadius)
708 bg_flags |= BG_NEEDS_BLUR;
709 else
681 bg_flags &= ~BG_NEEDS_BLUR; 710 bg_flags &= ~BG_NEEDS_BLUR;
682 else
683 bg_flags |= BG_NEEDS_BLUR;
684 711
685 return changed; 712 return changed;
686} 713}
687 714
688void 715void
689rxvt_term::set_tint_shade_flags () 716rxvt_term::set_tint_shade_flags ()
690{ 717{
718 if (shade != 100 || (bg_flags & BG_TINT_SET))
719 bg_flags |= BG_NEEDS_TINT;
720 else
721 bg_flags &= ~BG_NEEDS_TINT;
722}
723
724bool
725rxvt_term::bg_set_tint (rxvt_color &new_tint)
726{
727 if (!(bg_flags & BG_TINT_SET) || tint != new_tint)
728 {
729 tint = new_tint;
730 bg_flags |= BG_TINT_SET;
731
691 rgba c; 732 rgba c;
692 bool has_shade = shade != 100;
693
694 bg_flags &= ~BG_TINT_FLAGS;
695
696 if (bg_flags & BG_TINT_SET)
697 {
698 tint.get (c); 733 tint.get (c);
699 if (!has_shade
700 && (c.r <= 0x00ff || c.r >= 0xff00) 734 if ((c.r <= 0x00ff || c.r >= 0xff00)
701 && (c.g <= 0x00ff || c.g >= 0xff00) 735 && (c.g <= 0x00ff || c.g >= 0xff00)
702 && (c.b <= 0x00ff || c.b >= 0xff00)) 736 && (c.b <= 0x00ff || c.b >= 0xff00))
703 bg_flags |= BG_TINT_BITAND; 737 bg_flags |= BG_TINT_BITAND;
704 } 738 else
705
706 if (has_shade || (bg_flags & BG_TINT_SET))
707 bg_flags |= BG_NEEDS_TINT;
708}
709
710bool
711rxvt_term::bg_set_tint (rxvt_color &new_tint)
712{
713 if (!(bg_flags & BG_TINT_SET) || tint != new_tint)
714 {
715 tint = new_tint;
716 bg_flags |= BG_TINT_SET; 739 bg_flags &= ~BG_TINT_BITAND;
740
717 set_tint_shade_flags (); 741 set_tint_shade_flags ();
718 return true; 742 return true;
719 } 743 }
720 744
721 return false; 745 return false;
831bool 855bool
832rxvt_term::tint_pixmap (Pixmap pixmap, Visual *visual, int width, int height) 856rxvt_term::tint_pixmap (Pixmap pixmap, Visual *visual, int width, int height)
833{ 857{
834 bool ret = false; 858 bool ret = false;
835 859
836 if (bg_flags & BG_TINT_BITAND) 860 if (shade == 100 && (bg_flags & BG_TINT_BITAND))
837 { 861 {
838 XGCValues gcv; 862 XGCValues gcv;
839 GC gc; 863 GC gc;
840 864
841 /* In this case we can tint image server-side getting significant 865 /* In this case we can tint image server-side getting significant
922/* 946/*
923 * Builds a pixmap of the same size as the terminal window that contains 947 * Builds a pixmap of the same size as the terminal window that contains
924 * the tiled portion of the root pixmap that is supposed to be covered by 948 * the tiled portion of the root pixmap that is supposed to be covered by
925 * our window. 949 * our window.
926 */ 950 */
927unsigned long 951bool
928rxvt_term::make_transparency_pixmap () 952rxvt_term::make_transparency_pixmap ()
929{ 953{
930 unsigned long result = 0; 954 bool ret = false;
931 955
932 /* root dimensions may change from call to call - but Display structure should 956 /* root dimensions may change from call to call - but Display structure should
933 * be always up-to-date, so let's use it : 957 * be always up-to-date, so let's use it :
934 */ 958 */
935 int screen = display->screen; 959 int screen = display->screen;
1016 gc = XCreateGC (dpy, vt, GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin, &gcv); 1040 gc = XCreateGC (dpy, vt, GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin, &gcv);
1017 1041
1018 if (gc) 1042 if (gc)
1019 { 1043 {
1020 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height); 1044 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height);
1021 result |= BG_IS_VALID | (bg_flags & BG_EFFECTS_FLAGS); 1045 ret = true;
1046 unsigned long tr_flags = bg_flags & BG_EFFECTS_FLAGS;
1022 1047
1023 if (!(bg_flags & BG_CLIENT_RENDER)) 1048 if (!(bg_flags & BG_CLIENT_RENDER))
1024 { 1049 {
1025 if (bg_flags & BG_NEEDS_BLUR) 1050 if (bg_flags & BG_NEEDS_BLUR)
1026 { 1051 {
1027 if (blur_pixmap (bg_pixmap, visual, window_width, window_height, depth)) 1052 if (blur_pixmap (bg_pixmap, visual, window_width, window_height, depth))
1028 result &= ~BG_NEEDS_BLUR; 1053 tr_flags &= ~BG_NEEDS_BLUR;
1029 } 1054 }
1030 if (bg_flags & BG_NEEDS_TINT) 1055 if (bg_flags & BG_NEEDS_TINT)
1031 { 1056 {
1032 if (tint_pixmap (bg_pixmap, visual, window_width, window_height)) 1057 if (tint_pixmap (bg_pixmap, visual, window_width, window_height))
1033 result &= ~BG_NEEDS_TINT; 1058 tr_flags &= ~BG_NEEDS_TINT;
1034 } 1059 }
1035 if (result & BG_NEEDS_TINT) 1060 if (tr_flags & BG_NEEDS_TINT)
1036 { 1061 {
1037 XImage *ximage = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap); 1062 XImage *ximage = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap);
1038 if (ximage) 1063 if (ximage)
1039 { 1064 {
1040 /* our own client-side tinting */ 1065 /* our own client-side tinting */
1050 } 1075 }
1051 1076
1052 if (recoded_root_pmap != root_pixmap) 1077 if (recoded_root_pmap != root_pixmap)
1053 XFreePixmap (dpy, recoded_root_pmap); 1078 XFreePixmap (dpy, recoded_root_pmap);
1054 1079
1055 return result; 1080 return ret;
1056} 1081}
1057 1082
1058void 1083void
1059rxvt_term::bg_set_root_pixmap () 1084rxvt_term::bg_set_root_pixmap ()
1060{ 1085{
1067# endif /* ENABLE_TRANSPARENCY */ 1092# endif /* ENABLE_TRANSPARENCY */
1068 1093
1069bool 1094bool
1070rxvt_term::bg_render () 1095rxvt_term::bg_render ()
1071{ 1096{
1072 unsigned long tr_flags = 0; 1097 bool transparent = false;
1073 1098
1074 bg_invalidate (); 1099 bg_invalidate ();
1075# ifdef ENABLE_TRANSPARENCY 1100# ifdef ENABLE_TRANSPARENCY
1076 if (bg_flags & BG_IS_TRANSPARENT) 1101 if (bg_flags & BG_IS_TRANSPARENT)
1077 { 1102 {
1078 /* we need to re-generate transparency pixmap in that case ! */ 1103 /* we need to re-generate transparency pixmap in that case ! */
1079 tr_flags = make_transparency_pixmap (); 1104 transparent = make_transparency_pixmap ();
1080 if (tr_flags) 1105 if (transparent)
1081 bg_flags |= BG_IS_VALID; 1106 bg_flags |= BG_IS_VALID;
1082 } 1107 }
1083# endif 1108# endif
1084 1109
1085# ifdef BG_IMAGE_FROM_FILE 1110# ifdef BG_IMAGE_FROM_FILE
1086 if ((bg_flags & BG_IS_FROM_FILE) 1111 if (bg_flags & BG_IS_FROM_FILE)
1087 || (tr_flags & BG_EFFECTS_FLAGS))
1088 { 1112 {
1089 if (render_image (tr_flags)) 1113 if (render_image (transparent))
1090 bg_flags |= BG_IS_VALID; 1114 bg_flags |= BG_IS_VALID;
1091 } 1115 }
1092# endif 1116# endif
1093 1117
1094 if (!(bg_flags & BG_IS_VALID)) 1118 if (!(bg_flags & BG_IS_VALID))
1150} 1174}
1151 1175
1152void 1176void
1153rxvt_term::tint_ximage (Visual *visual, XImage *ximage) 1177rxvt_term::tint_ximage (Visual *visual, XImage *ximage)
1154{ 1178{
1179 unsigned int size_r, size_g, size_b;
1155 int sh_r, sh_g, sh_b; 1180 int sh_r, sh_g, sh_b;
1156 uint32_t mask_r, mask_g, mask_b; 1181 uint32_t mask_r, mask_g, mask_b;
1157 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b; 1182 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b;
1158 unsigned short low; 1183 unsigned short low;
1159 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 1184 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
1164 mask_r = visual->red_mask; 1189 mask_r = visual->red_mask;
1165 mask_g = visual->green_mask; 1190 mask_g = visual->green_mask;
1166 mask_b = visual->blue_mask; 1191 mask_b = visual->blue_mask;
1167 1192
1168 /* boring lookup table pre-initialization */ 1193 /* boring lookup table pre-initialization */
1169 switch (ximage->depth) 1194 sh_r = ecb_ctz32 (mask_r);
1170 { 1195 sh_g = ecb_ctz32 (mask_g);
1171 case 15: 1196 sh_b = ecb_ctz32 (mask_b);
1172 if ((mask_r != 0x7c00) || 1197
1173 (mask_g != 0x03e0) || 1198 size_r = mask_r >> sh_r;
1174 (mask_b != 0x001f)) 1199 size_g = mask_g >> sh_g;
1200 size_b = mask_b >> sh_b;
1201
1202 if (size_r++ > 255 || size_g++ > 255 || size_b++ > 255)
1175 return; 1203 return;
1176 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(32+32+32)); 1204
1205 lookup = (uint32_t *)malloc (sizeof (uint32_t) * (size_r + size_g + size_b));
1177 lookup_r = lookup; 1206 lookup_r = lookup;
1178 lookup_g = lookup+32; 1207 lookup_g = lookup + size_r;
1179 lookup_b = lookup+32+32; 1208 lookup_b = lookup + size_r + size_g;
1180 sh_r = 10;
1181 sh_g = 5;
1182 sh_b = 0;
1183 break;
1184 case 16:
1185 if ((mask_r != 0xf800) ||
1186 (mask_g != 0x07e0) ||
1187 (mask_b != 0x001f))
1188 return;
1189 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(32+64+32));
1190 lookup_r = lookup;
1191 lookup_g = lookup+32;
1192 lookup_b = lookup+32+64;
1193 sh_r = 11;
1194 sh_g = 5;
1195 sh_b = 0;
1196 break;
1197 case 24:
1198 if ((mask_r != 0xff0000) ||
1199 (mask_g != 0x00ff00) ||
1200 (mask_b != 0x0000ff))
1201 return;
1202 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(256+256+256));
1203 lookup_r = lookup;
1204 lookup_g = lookup+256;
1205 lookup_b = lookup+256+256;
1206 sh_r = 16;
1207 sh_g = 8;
1208 sh_b = 0;
1209 break;
1210 case 32:
1211 if ((mask_r != 0xff0000) ||
1212 (mask_g != 0x00ff00) ||
1213 (mask_b != 0x0000ff))
1214 return;
1215 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(256+256+256));
1216 lookup_r = lookup;
1217 lookup_g = lookup+256;
1218 lookup_b = lookup+256+256;
1219 sh_r = 16;
1220 sh_g = 8;
1221 sh_b = 0;
1222 break;
1223 default:
1224 return; /* we do not support this color depth */
1225 }
1226 1209
1227 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); 1210 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1228 1211
1229 if (bg_flags & BG_TINT_SET) 1212 if (bg_flags & BG_TINT_SET)
1230 tint.get (c); 1213 tint.get (c);
1252 fill_lut (lookup_g, mask_g, sh_g, low, c.g); 1235 fill_lut (lookup_g, mask_g, sh_g, low, c.g);
1253 fill_lut (lookup_b, mask_b, sh_b, low, c.b); 1236 fill_lut (lookup_b, mask_b, sh_b, low, c.b);
1254 1237
1255 /* apply table to input image (replacing colors by newly calculated ones) */ 1238 /* apply table to input image (replacing colors by newly calculated ones) */
1256 if (ximage->bits_per_pixel == 32 1239 if (ximage->bits_per_pixel == 32
1257 && (ximage->depth == 24 || ximage->depth == 32)
1258 && ximage->byte_order == host_byte_order) 1240 && ximage->byte_order == host_byte_order)
1259 { 1241 {
1260 uint32_t *p1, *pf, *p, *pl; 1242 char *line = ximage->data;
1261 p1 = (uint32_t *) ximage->data;
1262 pf = (uint32_t *) (ximage->data + ximage->height * ximage->bytes_per_line);
1263 1243
1264 while (p1 < pf) 1244 for (int y = 0; y < ximage->height; y++)
1265 {
1266 p = p1;
1267 pl = p1 + ximage->width;
1268 for (; p < pl; p++)
1269 { 1245 {
1270 *p = lookup_r[(*p & 0xff0000) >> 16] | 1246 uint32_t *p = (uint32_t *)line;
1271 lookup_g[(*p & 0x00ff00) >> 8] | 1247 for (int x = 0; x < ximage->width; x++)
1272 lookup_b[(*p & 0x0000ff)] |
1273 (*p & 0xff000000);
1274 } 1248 {
1275 p1 = (uint32_t *) ((char *) p1 + ximage->bytes_per_line); 1249 *p = lookup_r[(*p & mask_r) >> sh_r] |
1250 lookup_g[(*p & mask_g) >> sh_g] |
1251 lookup_b[(*p & mask_b) >> sh_b];
1252 p++;
1253 }
1254 line += ximage->bytes_per_line;
1276 } 1255 }
1277 } 1256 }
1278 else 1257 else
1279 { 1258 {
1280 for (int y = 0; y < ximage->height; y++) 1259 for (int y = 0; y < ximage->height; y++)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines