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.206 by sf-exg, Thu Apr 12 10:22:50 2012 UTC vs.
Revision 1.209 by sf-exg, Fri May 11 12:21:22 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.
348 unsigned int width, unsigned int height) 348 unsigned int width, unsigned int height)
349{ 349{
350 XImage *ximage; 350 XImage *ximage;
351 char *data, *line; 351 char *data, *line;
352 int bytes_per_pixel; 352 int bytes_per_pixel;
353 int width_r, width_g, width_b; 353 int width_r, width_g, width_b, width_a;
354 int sh_r, sh_g, sh_b; 354 int sh_r, sh_g, sh_b, sh_a;
355 uint32_t alpha_mask;
355 int rowstride; 356 int rowstride;
356 int channels; 357 int channels;
357 unsigned char *row; 358 unsigned char *row;
358 359
359 if (visual->c_class != TrueColor) 360 if (visual->c_class != TrueColor)
360 return false; 361 return false;
362
363#if XRENDER
364 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
365 if (format)
366 alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha;
367 else
368#endif
369 alpha_mask = 0;
361 370
362 if (depth == 24 || depth == 32) 371 if (depth == 24 || depth == 32)
363 bytes_per_pixel = 4; 372 bytes_per_pixel = 4;
364 else if (depth == 15 || depth == 16) 373 else if (depth == 15 || depth == 16)
365 bytes_per_pixel = 2; 374 bytes_per_pixel = 2;
367 return false; 376 return false;
368 377
369 width_r = ecb_popcount32 (visual->red_mask); 378 width_r = ecb_popcount32 (visual->red_mask);
370 width_g = ecb_popcount32 (visual->green_mask); 379 width_g = ecb_popcount32 (visual->green_mask);
371 width_b = ecb_popcount32 (visual->blue_mask); 380 width_b = ecb_popcount32 (visual->blue_mask);
381 width_a = ecb_popcount32 (alpha_mask);
372 382
373 if (width_r > 8 || width_g > 8 || width_b > 8) 383 if (width_r > 8 || width_g > 8 || width_b > 8 || width_a > 8)
374 return false; 384 return false;
375 385
376 sh_r = ecb_ctz32 (visual->red_mask); 386 sh_r = ecb_ctz32 (visual->red_mask);
377 sh_g = ecb_ctz32 (visual->green_mask); 387 sh_g = ecb_ctz32 (visual->green_mask);
378 sh_b = ecb_ctz32 (visual->blue_mask); 388 sh_b = ecb_ctz32 (visual->blue_mask);
389 sh_a = ecb_ctz32 (alpha_mask);
379 390
380 if (width > INT_MAX / height / bytes_per_pixel) 391 if (width > INT_MAX / height / bytes_per_pixel)
381 return false; 392 return false;
382 393
383 data = (char *)malloc (width * height * bytes_per_pixel); 394 data = (char *)malloc (width * height * bytes_per_pixel);
397 rowstride = gdk_pixbuf_get_rowstride (pixbuf); 408 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
398 channels = gdk_pixbuf_get_n_channels (pixbuf); 409 channels = gdk_pixbuf_get_n_channels (pixbuf);
399 row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels; 410 row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels;
400 line = data; 411 line = data;
401 412
413 rgba c (0, 0, 0);
414
415 if (channels == 4 && alpha_mask == 0)
416 {
417 pix_colors[Color_bg].get (c);
418 c.r >>= 8;
419 c.g >>= 8;
420 c.b >>= 8;
421 }
422
402 for (int y = 0; y < height; y++) 423 for (int y = 0; y < height; y++)
403 { 424 {
404 for (int x = 0; x < width; x++) 425 for (int x = 0; x < width; x++)
405 { 426 {
406 unsigned char *pixel = row + x * channels; 427 unsigned char *pixel = row + x * channels;
407 uint32_t value; 428 uint32_t value;
429 unsigned char r, g, b, a;
408 430
431 if (channels == 4)
432 {
433 a = pixel[3];
434 r = (pixel[0] * a + c.r * (0xff - a)) / 0xff;
435 g = (pixel[1] * a + c.g * (0xff - a)) / 0xff;
436 b = (pixel[2] * a + c.b * (0xff - a)) / 0xff;
437 }
438 else
439 {
440 a = 0xff;
441 r = pixel[0];
442 g = pixel[1];
443 b = pixel[2];
444 }
445
409 value = ((pixel[0] >> (8 - width_r)) << sh_r) 446 value = ((r >> (8 - width_r)) << sh_r)
410 | ((pixel[1] >> (8 - width_g)) << sh_g) 447 | ((g >> (8 - width_g)) << sh_g)
411 | ((pixel[2] >> (8 - width_b)) << sh_b); 448 | ((b >> (8 - width_b)) << sh_b)
449 | ((a >> (8 - width_a)) << sh_a);
412 450
413 if (bytes_per_pixel == 4) 451 if (bytes_per_pixel == 4)
414 ((uint32_t *)line)[x] = value; 452 ((uint32_t *)line)[x] = value;
415 else 453 else
416 ((uint16_t *)line)[x] = value; 454 ((uint16_t *)line)[x] = value;
1144} 1182}
1145 1183
1146void 1184void
1147rxvt_term::tint_ximage (Visual *visual, XImage *ximage) 1185rxvt_term::tint_ximage (Visual *visual, XImage *ximage)
1148{ 1186{
1187 unsigned int size_r, size_g, size_b;
1149 int sh_r, sh_g, sh_b; 1188 int sh_r, sh_g, sh_b;
1150 uint32_t mask_r, mask_g, mask_b; 1189 uint32_t mask_r, mask_g, mask_b;
1151 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b; 1190 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b;
1152 unsigned short low; 1191 unsigned short low;
1153 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 1192 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
1158 mask_r = visual->red_mask; 1197 mask_r = visual->red_mask;
1159 mask_g = visual->green_mask; 1198 mask_g = visual->green_mask;
1160 mask_b = visual->blue_mask; 1199 mask_b = visual->blue_mask;
1161 1200
1162 /* boring lookup table pre-initialization */ 1201 /* boring lookup table pre-initialization */
1163 switch (ximage->depth) 1202 sh_r = ecb_ctz32 (mask_r);
1164 { 1203 sh_g = ecb_ctz32 (mask_g);
1165 case 15: 1204 sh_b = ecb_ctz32 (mask_b);
1166 if ((mask_r != 0x7c00) || 1205
1167 (mask_g != 0x03e0) || 1206 size_r = mask_r >> sh_r;
1168 (mask_b != 0x001f)) 1207 size_g = mask_g >> sh_g;
1208 size_b = mask_b >> sh_b;
1209
1210 if (size_r++ > 255 || size_g++ > 255 || size_b++ > 255)
1169 return; 1211 return;
1170 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(32+32+32)); 1212
1213 lookup = (uint32_t *)malloc (sizeof (uint32_t) * (size_r + size_g + size_b));
1171 lookup_r = lookup; 1214 lookup_r = lookup;
1172 lookup_g = lookup+32; 1215 lookup_g = lookup + size_r;
1173 lookup_b = lookup+32+32; 1216 lookup_b = lookup + size_r + size_g;
1174 sh_r = 10;
1175 sh_g = 5;
1176 sh_b = 0;
1177 break;
1178 case 16:
1179 if ((mask_r != 0xf800) ||
1180 (mask_g != 0x07e0) ||
1181 (mask_b != 0x001f))
1182 return;
1183 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(32+64+32));
1184 lookup_r = lookup;
1185 lookup_g = lookup+32;
1186 lookup_b = lookup+32+64;
1187 sh_r = 11;
1188 sh_g = 5;
1189 sh_b = 0;
1190 break;
1191 case 24:
1192 if ((mask_r != 0xff0000) ||
1193 (mask_g != 0x00ff00) ||
1194 (mask_b != 0x0000ff))
1195 return;
1196 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(256+256+256));
1197 lookup_r = lookup;
1198 lookup_g = lookup+256;
1199 lookup_b = lookup+256+256;
1200 sh_r = 16;
1201 sh_g = 8;
1202 sh_b = 0;
1203 break;
1204 case 32:
1205 if ((mask_r != 0xff0000) ||
1206 (mask_g != 0x00ff00) ||
1207 (mask_b != 0x0000ff))
1208 return;
1209 lookup = (uint32_t *) malloc (sizeof (uint32_t)*(256+256+256));
1210 lookup_r = lookup;
1211 lookup_g = lookup+256;
1212 lookup_b = lookup+256+256;
1213 sh_r = 16;
1214 sh_g = 8;
1215 sh_b = 0;
1216 break;
1217 default:
1218 return; /* we do not support this color depth */
1219 }
1220 1217
1221 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); 1218 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1222 1219
1223 if (bg_flags & BG_TINT_SET) 1220 if (bg_flags & BG_TINT_SET)
1224 tint.get (c); 1221 tint.get (c);
1246 fill_lut (lookup_g, mask_g, sh_g, low, c.g); 1243 fill_lut (lookup_g, mask_g, sh_g, low, c.g);
1247 fill_lut (lookup_b, mask_b, sh_b, low, c.b); 1244 fill_lut (lookup_b, mask_b, sh_b, low, c.b);
1248 1245
1249 /* apply table to input image (replacing colors by newly calculated ones) */ 1246 /* apply table to input image (replacing colors by newly calculated ones) */
1250 if (ximage->bits_per_pixel == 32 1247 if (ximage->bits_per_pixel == 32
1251 && (ximage->depth == 24 || ximage->depth == 32)
1252 && ximage->byte_order == host_byte_order) 1248 && ximage->byte_order == host_byte_order)
1253 { 1249 {
1254 uint32_t *p1, *pf, *p, *pl; 1250 char *line = ximage->data;
1255 p1 = (uint32_t *) ximage->data;
1256 pf = (uint32_t *) (ximage->data + ximage->height * ximage->bytes_per_line);
1257 1251
1258 while (p1 < pf) 1252 for (int y = 0; y < ximage->height; y++)
1259 {
1260 p = p1;
1261 pl = p1 + ximage->width;
1262 for (; p < pl; p++)
1263 { 1253 {
1264 *p = lookup_r[(*p & 0xff0000) >> 16] | 1254 uint32_t *p = (uint32_t *)line;
1265 lookup_g[(*p & 0x00ff00) >> 8] | 1255 for (int x = 0; x < ximage->width; x++)
1266 lookup_b[(*p & 0x0000ff)] |
1267 (*p & 0xff000000);
1268 } 1256 {
1269 p1 = (uint32_t *) ((char *) p1 + ximage->bytes_per_line); 1257 *p = lookup_r[(*p & mask_r) >> sh_r] |
1258 lookup_g[(*p & mask_g) >> sh_g] |
1259 lookup_b[(*p & mask_b) >> sh_b];
1260 p++;
1261 }
1262 line += ximage->bytes_per_line;
1270 } 1263 }
1271 } 1264 }
1272 else 1265 else
1273 { 1266 {
1274 for (int y = 0; y < ximage->height; y++) 1267 for (int y = 0; y < ximage->height; y++)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines