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.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.
346rxvt_term::pixbuf_to_pixmap (GdkPixbuf *pixbuf, Pixmap pixmap, GC gc, 346rxvt_term::pixbuf_to_pixmap (GdkPixbuf *pixbuf, Pixmap pixmap, GC gc,
347 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,
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 *line;
352 int bytes_per_pixel;
353 int width_r, width_g, width_b; 352 int width_r, width_g, width_b, width_a;
354 int sh_r, sh_g, sh_b; 353 int sh_r, sh_g, sh_b, sh_a;
354 uint32_t alpha_mask;
355 int rowstride; 355 int rowstride;
356 int channels; 356 int channels;
357 unsigned char *row; 357 unsigned char *row;
358 358
359 if (visual->c_class != TrueColor) 359 if (visual->c_class != TrueColor)
360 return false; 360 return false;
361 361
362 if (depth == 24 || depth == 32) 362#if XRENDER
363 bytes_per_pixel = 4; 363 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
364 else if (depth == 15 || depth == 16) 364 if (format)
365 bytes_per_pixel = 2; 365 alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha;
366 else 366 else
367 return false; 367#endif
368 alpha_mask = 0;
368 369
369 width_r = ecb_popcount32 (visual->red_mask); 370 width_r = ecb_popcount32 (visual->red_mask);
370 width_g = ecb_popcount32 (visual->green_mask); 371 width_g = ecb_popcount32 (visual->green_mask);
371 width_b = ecb_popcount32 (visual->blue_mask); 372 width_b = ecb_popcount32 (visual->blue_mask);
373 width_a = ecb_popcount32 (alpha_mask);
372 374
373 if (width_r > 8 || width_g > 8 || width_b > 8) 375 if (width_r > 8 || width_g > 8 || width_b > 8 || width_a > 8)
374 return false; 376 return false;
375 377
376 sh_r = ecb_ctz32 (visual->red_mask); 378 sh_r = ecb_ctz32 (visual->red_mask);
377 sh_g = ecb_ctz32 (visual->green_mask); 379 sh_g = ecb_ctz32 (visual->green_mask);
378 sh_b = ecb_ctz32 (visual->blue_mask); 380 sh_b = ecb_ctz32 (visual->blue_mask);
381 sh_a = ecb_ctz32 (alpha_mask);
379 382
380 if (width > INT_MAX / height / bytes_per_pixel) 383 if (width > 32767 || height > 32767)
381 return false; 384 return false;
382 385
383 data = (char *)malloc (width * height * bytes_per_pixel); 386 ximage = XCreateImage (dpy, visual, depth, ZPixmap, 0, 0,
384 if (!data) 387 width, height, 32, 0);
388 if (!ximage)
385 return false; 389 return false;
386 390
387 ximage = XCreateImage (dpy, visual, depth, ZPixmap, 0, data, 391 if (height > INT_MAX / ximage->bytes_per_line
388 width, height, bytes_per_pixel * 8, 0); 392 || !(ximage->data = (char *)malloc (height * ximage->bytes_per_line)))
389 if (!ximage)
390 { 393 {
391 free (data); 394 XDestroyImage (ximage);
392 return false; 395 return false;
393 } 396 }
394 397
395 ximage->byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 398 ximage->byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
396 399
397 rowstride = gdk_pixbuf_get_rowstride (pixbuf); 400 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
398 channels = gdk_pixbuf_get_n_channels (pixbuf); 401 channels = gdk_pixbuf_get_n_channels (pixbuf);
399 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;
400 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 }
401 414
402 for (int y = 0; y < height; y++) 415 for (int y = 0; y < height; y++)
403 { 416 {
404 for (int x = 0; x < width; x++) 417 for (int x = 0; x < width; x++)
405 { 418 {
406 unsigned char *pixel = row + x * channels; 419 unsigned char *pixel = row + x * channels;
407 uint32_t value; 420 uint32_t value;
421 unsigned char r, g, b, a;
408 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
409 value = ((pixel[0] >> (8 - width_r)) << sh_r) 438 value = ((r >> (8 - width_r)) << sh_r)
410 | ((pixel[1] >> (8 - width_g)) << sh_g) 439 | ((g >> (8 - width_g)) << sh_g)
411 | ((pixel[2] >> (8 - width_b)) << sh_b); 440 | ((b >> (8 - width_b)) << sh_b)
441 | ((a >> (8 - width_a)) << sh_a);
412 442
413 if (bytes_per_pixel == 4) 443 if (ximage->bits_per_pixel == 32)
414 ((uint32_t *)line)[x] = value; 444 ((uint32_t *)line)[x] = value;
415 else 445 else
416 ((uint16_t *)line)[x] = value; 446 XPutPixel (ximage, x, y, value);
417 } 447 }
418 448
419 row += rowstride; 449 row += rowstride;
420 line += ximage->bytes_per_line; 450 line += ximage->bytes_per_line;
421 } 451 }
1144} 1174}
1145 1175
1146void 1176void
1147rxvt_term::tint_ximage (Visual *visual, XImage *ximage) 1177rxvt_term::tint_ximage (Visual *visual, XImage *ximage)
1148{ 1178{
1179 unsigned int size_r, size_g, size_b;
1149 int sh_r, sh_g, sh_b; 1180 int sh_r, sh_g, sh_b;
1150 uint32_t mask_r, mask_g, mask_b; 1181 uint32_t mask_r, mask_g, mask_b;
1151 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b; 1182 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b;
1152 unsigned short low; 1183 unsigned short low;
1153 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 1184 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
1158 mask_r = visual->red_mask; 1189 mask_r = visual->red_mask;
1159 mask_g = visual->green_mask; 1190 mask_g = visual->green_mask;
1160 mask_b = visual->blue_mask; 1191 mask_b = visual->blue_mask;
1161 1192
1162 /* boring lookup table pre-initialization */ 1193 /* boring lookup table pre-initialization */
1163 switch (ximage->depth) 1194 sh_r = ecb_ctz32 (mask_r);
1164 { 1195 sh_g = ecb_ctz32 (mask_g);
1165 case 15: 1196 sh_b = ecb_ctz32 (mask_b);
1166 if ((mask_r != 0x7c00) || 1197
1167 (mask_g != 0x03e0) || 1198 size_r = mask_r >> sh_r;
1168 (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)
1169 return; 1203 return;
1170 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));
1171 lookup_r = lookup; 1206 lookup_r = lookup;
1172 lookup_g = lookup+32; 1207 lookup_g = lookup + size_r;
1173 lookup_b = lookup+32+32; 1208 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 1209
1221 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); 1210 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1222 1211
1223 if (bg_flags & BG_TINT_SET) 1212 if (bg_flags & BG_TINT_SET)
1224 tint.get (c); 1213 tint.get (c);
1246 fill_lut (lookup_g, mask_g, sh_g, low, c.g); 1235 fill_lut (lookup_g, mask_g, sh_g, low, c.g);
1247 fill_lut (lookup_b, mask_b, sh_b, low, c.b); 1236 fill_lut (lookup_b, mask_b, sh_b, low, c.b);
1248 1237
1249 /* apply table to input image (replacing colors by newly calculated ones) */ 1238 /* apply table to input image (replacing colors by newly calculated ones) */
1250 if (ximage->bits_per_pixel == 32 1239 if (ximage->bits_per_pixel == 32
1251 && (ximage->depth == 24 || ximage->depth == 32)
1252 && ximage->byte_order == host_byte_order) 1240 && ximage->byte_order == host_byte_order)
1253 { 1241 {
1254 uint32_t *p1, *pf, *p, *pl; 1242 char *line = ximage->data;
1255 p1 = (uint32_t *) ximage->data;
1256 pf = (uint32_t *) (ximage->data + ximage->height * ximage->bytes_per_line);
1257 1243
1258 while (p1 < pf) 1244 for (int y = 0; y < ximage->height; y++)
1259 {
1260 p = p1;
1261 pl = p1 + ximage->width;
1262 for (; p < pl; p++)
1263 { 1245 {
1264 *p = lookup_r[(*p & 0xff0000) >> 16] | 1246 uint32_t *p = (uint32_t *)line;
1265 lookup_g[(*p & 0x00ff00) >> 8] | 1247 for (int x = 0; x < ximage->width; x++)
1266 lookup_b[(*p & 0x0000ff)] |
1267 (*p & 0xff000000);
1268 } 1248 {
1269 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;
1270 } 1255 }
1271 } 1256 }
1272 else 1257 else
1273 { 1258 {
1274 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