]>
Dogcows Code - chaz/openbox/blob - src/image.cc
1 // -*- mode: C++; indent-tabs-mode: nil; -*-
4 # include "../config.h"
5 #endif // HAVE_CONFIG_H
15 #include "blackbox.hh"
16 #include "basedisplay.hh"
22 BImage::BImage(BImageControl
*c
, int w
, int h
) {
25 width
= (w
> 0) ? w
: 1;
26 height
= (h
> 0) ? h
: 1;
28 red
= new unsigned char[width
* height
];
29 green
= new unsigned char[width
* height
];
30 blue
= new unsigned char[width
* height
];
32 xtable
= ytable
= (unsigned int *) 0;
34 cpc
= control
->getColorsPerChannel();
37 control
->getColorTables(&red_table
, &green_table
, &blue_table
,
38 &red_offset
, &green_offset
, &blue_offset
,
39 &red_bits
, &green_bits
, &blue_bits
);
41 if (control
->getVisual()->c_class
!= TrueColor
)
42 control
->getXColorTable(&colors
, &ncolors
);
46 BImage::~BImage(void) {
53 Pixmap
BImage::render(const BTexture
&texture
) {
54 if (texture
.texture() & BTexture::Parent_Relative
)
55 return ParentRelative
;
56 else if (texture
.texture() & BTexture::Solid
)
57 return render_solid(texture
);
58 else if (texture
.texture() & BTexture::Gradient
)
59 return render_gradient(texture
);
64 Pixmap
BImage::render_solid(const BTexture
&texture
) {
65 Pixmap pixmap
= XCreatePixmap(control
->getBaseDisplay()->getXDisplay(),
66 control
->getDrawable(), width
,
67 height
, control
->getDepth());
69 fprintf(stderr
, "BImage::render_solid: error creating pixmap\n");
73 Display
*display
= control
->getBaseDisplay()->getXDisplay();
75 BPen
pen(texture
.color());
76 BPen
penlight(texture
.lightColor());
77 BPen
penshadow(texture
.shadowColor());
79 XFillRectangle(display
, pixmap
, pen
.gc(), 0, 0, width
, height
);
81 if (texture
.texture() & BTexture::Interlaced
) {
82 BPen
peninterlace(texture
.colorTo());
83 for (unsigned int i
= 0; i
< height
; i
+= 2)
84 XDrawLine(display
, pixmap
, peninterlace
.gc(), 0, i
, width
, i
);
87 int left
= 0, top
= 0, right
= width
- 1, bottom
= height
- 1;
89 if (texture
.texture() & BTexture::Border
) {
90 BPen
penborder(texture
.borderColor());
91 XDrawRectangle(display
, pixmap
, penborder
.gc(),
92 left
, top
, right
, bottom
);
95 if (texture
.texture() & BTexture::Bevel1
) {
96 if (texture
.texture() & BTexture::Raised
) {
97 XDrawLine(display
, pixmap
, penshadow
.gc(),
98 left
, bottom
, right
, bottom
);
99 XDrawLine(display
, pixmap
, penshadow
.gc(),
100 right
, bottom
, right
, top
);
102 XDrawLine(display
, pixmap
, penlight
.gc(),
103 left
, top
, right
, top
);
104 XDrawLine(display
, pixmap
, penlight
.gc(),
105 left
, bottom
, left
, top
);
106 } else if (texture
.texture() & BTexture::Sunken
) {
107 XDrawLine(display
, pixmap
, penlight
.gc(),
108 left
, bottom
, right
, bottom
);
109 XDrawLine(display
, pixmap
, penlight
.gc(),
110 right
, bottom
, right
, top
);
112 XDrawLine(display
, pixmap
, penshadow
.gc(),
113 left
, top
, right
, top
);
114 XDrawLine(display
, pixmap
, penshadow
.gc(),
115 left
, bottom
, left
, top
);
117 } else if (texture
.texture() & BTexture::Bevel2
) {
118 if (texture
.texture() & BTexture::Raised
) {
119 XDrawLine(display
, pixmap
, penshadow
.gc(),
120 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
121 XDrawLine(display
, pixmap
, penshadow
.gc(),
122 right
- 2, bottom
- 2, right
- 2, top
+ 1);
124 XDrawLine(display
, pixmap
, penlight
.gc(),
125 left
+ 1, top
+ 1, right
- 2, top
+ 1);
126 XDrawLine(display
, pixmap
, penlight
.gc(),
127 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
128 } else if (texture
.texture() & BTexture::Sunken
) {
129 XDrawLine(display
, pixmap
, penlight
.gc(),
130 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
131 XDrawLine(display
, pixmap
, penlight
.gc(),
132 right
- 2, bottom
- 2, right
- 2, top
+ 1);
134 XDrawLine(display
, pixmap
, penshadow
.gc(),
135 left
+ 1, top
+ 1, right
- 2, top
+ 1);
136 XDrawLine(display
, pixmap
, penshadow
.gc(),
137 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
145 Pixmap
BImage::render_gradient(const BTexture
&texture
) {
146 bool inverted
= False
;
148 interlaced
= texture
.texture() & BTexture::Interlaced
;
150 if (texture
.texture() & BTexture::Sunken
) {
151 from
= texture
.colorTo();
152 to
= texture
.color();
154 if (! (texture
.texture() & BTexture::Invert
)) inverted
= True
;
156 from
= texture
.color();
157 to
= texture
.colorTo();
159 if (texture
.texture() & BTexture::Invert
) inverted
= True
;
162 control
->getGradientBuffers(width
, height
, &xtable
, &ytable
);
164 if (texture
.texture() & BTexture::Diagonal
) dgradient();
165 else if (texture
.texture() & BTexture::Elliptic
) egradient();
166 else if (texture
.texture() & BTexture::Horizontal
) hgradient();
167 else if (texture
.texture() & BTexture::Pyramid
) pgradient();
168 else if (texture
.texture() & BTexture::Rectangle
) rgradient();
169 else if (texture
.texture() & BTexture::Vertical
) vgradient();
170 else if (texture
.texture() & BTexture::CrossDiagonal
) cdgradient();
171 else if (texture
.texture() & BTexture::PipeCross
) pcgradient();
173 if (texture
.texture() & BTexture::Bevel1
) bevel1();
174 else if (texture
.texture() & BTexture::Bevel2
) bevel2();
176 if (texture
.texture() & BTexture::Border
) border(texture
);
178 if (inverted
) invert();
180 return renderPixmap();
185 static const unsigned char dither4
[4][4] = {
194 * Helper function for TrueColorDither and renderXImage
196 * This handles the proper setting of the image data based on the image depth
197 * and the machine's byte ordering
200 void assignPixelData(unsigned int bit_depth
, unsigned char **data
,
201 unsigned long pixel
) {
202 unsigned char *pixel_data
= *data
;
205 *pixel_data
++ = pixel
;
208 case 16: // 16bpp LSB
209 *pixel_data
++ = pixel
;
210 *pixel_data
++ = pixel
>> 8;
213 case 17: // 16bpp MSB
214 *pixel_data
++ = pixel
>> 8;
215 *pixel_data
++ = pixel
;
218 case 24: // 24bpp LSB
219 *pixel_data
++ = pixel
;
220 *pixel_data
++ = pixel
>> 8;
221 *pixel_data
++ = pixel
>> 16;
224 case 25: // 24bpp MSB
225 *pixel_data
++ = pixel
>> 16;
226 *pixel_data
++ = pixel
>> 8;
227 *pixel_data
++ = pixel
;
230 case 32: // 32bpp LSB
231 *pixel_data
++ = pixel
;
232 *pixel_data
++ = pixel
>> 8;
233 *pixel_data
++ = pixel
>> 16;
234 *pixel_data
++ = pixel
>> 24;
237 case 33: // 32bpp MSB
238 *pixel_data
++ = pixel
>> 24;
239 *pixel_data
++ = pixel
>> 16;
240 *pixel_data
++ = pixel
>> 8;
241 *pixel_data
++ = pixel
;
244 *data
= pixel_data
; // assign back so we don't lose our place
248 // algorithm: ordered dithering... many many thanks to rasterman
249 // (raster@rasterman.com) for telling me about this... portions of this
250 // code is based off of his code in Imlib
251 void BImage::TrueColorDither(unsigned int bit_depth
, int bytes_per_line
,
252 unsigned char *pixel_data
) {
253 unsigned int x
, y
, dithx
, dithy
, r
, g
, b
, er
, eg
, eb
, offset
;
254 unsigned char *ppixel_data
= pixel_data
;
257 for (y
= 0, offset
= 0; y
< height
; y
++) {
260 for (x
= 0; x
< width
; x
++, offset
++) {
266 er
= r
& (red_bits
- 1);
267 eg
= g
& (green_bits
- 1);
268 eb
= b
& (blue_bits
- 1);
274 if ((dither4
[dithy
][dithx
] < er
) && (r
< red_table
[255])) r
++;
275 if ((dither4
[dithy
][dithx
] < eg
) && (g
< green_table
[255])) g
++;
276 if ((dither4
[dithy
][dithx
] < eb
) && (b
< blue_table
[255])) b
++;
278 pixel
= (r
<< red_offset
) | (g
<< green_offset
) | (b
<< blue_offset
);
279 assignPixelData(bit_depth
, &pixel_data
, pixel
);
282 pixel_data
= (ppixel_data
+= bytes_per_line
);
287 const static unsigned char dither8
[8][8] = {
288 { 0, 32, 8, 40, 2, 34, 10, 42},
289 { 48, 16, 56, 24, 50, 18, 58, 26},
290 { 12, 44, 4, 36, 14, 46, 6, 38},
291 { 60, 28, 52, 20, 62, 30, 54, 22},
292 { 3, 35, 11, 43, 1, 33, 9, 41},
293 { 51, 19, 59, 27, 49, 17, 57, 25},
294 { 15, 47, 7, 39, 13, 45, 5, 37},
295 { 63, 31, 55, 23, 61, 29, 53, 21}
298 void BImage::OrderedPseudoColorDither(int bytes_per_line
,
299 unsigned char *pixel_data
) {
300 unsigned int x
, y
, dithx
, dithy
, r
, g
, b
, er
, eg
, eb
, offset
;
302 unsigned char *ppixel_data
= pixel_data
;
304 for (y
= 0, offset
= 0; y
< height
; y
++) {
307 for (x
= 0; x
< width
; x
++, offset
++) {
314 er
= r
& (red_bits
- 1);
315 eg
= g
& (green_bits
- 1);
316 eb
= b
& (blue_bits
- 1);
322 if ((dither8
[dithy
][dithx
] < er
) && (r
< red_table
[255])) r
++;
323 if ((dither8
[dithy
][dithx
] < eg
) && (g
< green_table
[255])) g
++;
324 if ((dither8
[dithy
][dithx
] < eb
) && (b
< blue_table
[255])) b
++;
326 pixel
= (r
* cpccpc
) + (g
* cpc
) + b
;
327 *(pixel_data
++) = colors
[pixel
].pixel
;
330 pixel_data
= (ppixel_data
+= bytes_per_line
);
335 void BImage::PseudoColorDither(int bytes_per_line
, unsigned char *pixel_data
) {
337 *rerr
= new short[width
+ 2],
338 *gerr
= new short[width
+ 2],
339 *berr
= new short[width
+ 2],
340 *nrerr
= new short[width
+ 2],
341 *ngerr
= new short[width
+ 2],
342 *nberr
= new short[width
+ 2];
344 int rr
, gg
, bb
, rer
, ger
, ber
;
345 int dd
= 255 / control
->getColorsPerChannel();
346 unsigned int x
, y
, r
, g
, b
, offset
;
348 unsigned char *ppixel_data
= pixel_data
;
350 for (x
= 0; x
< width
; x
++) {
351 *(rerr
+ x
) = *(red
+ x
);
352 *(gerr
+ x
) = *(green
+ x
);
353 *(berr
+ x
) = *(blue
+ x
);
356 *(rerr
+ x
) = *(gerr
+ x
) = *(berr
+ x
) = 0;
358 for (y
= 0, offset
= 0; y
< height
; y
++) {
359 if (y
< (height
- 1)) {
360 int i
= offset
+ width
;
361 for (x
= 0; x
< width
; x
++, i
++) {
362 *(nrerr
+ x
) = *(red
+ i
);
363 *(ngerr
+ x
) = *(green
+ i
);
364 *(nberr
+ x
) = *(blue
+ i
);
367 *(nrerr
+ x
) = *(red
+ (--i
));
368 *(ngerr
+ x
) = *(green
+ i
);
369 *(nberr
+ x
) = *(blue
+ i
);
372 for (x
= 0; x
< width
; x
++) {
377 if (rr
> 255) rr
= 255; else if (rr
< 0) rr
= 0;
378 if (gg
> 255) gg
= 255; else if (gg
< 0) gg
= 0;
379 if (bb
> 255) bb
= 255; else if (bb
< 0) bb
= 0;
385 rer
= rerr
[x
] - r
*dd
;
386 ger
= gerr
[x
] - g
*dd
;
387 ber
= berr
[x
] - b
*dd
;
389 pixel
= (r
* cpccpc
) + (g
* cpc
) + b
;
390 *pixel_data
++ = colors
[pixel
].pixel
;
405 pixel_data
= (ppixel_data
+= bytes_per_line
);
428 XImage
*BImage::renderXImage(void) {
430 XCreateImage(control
->getBaseDisplay()->getXDisplay(),
431 control
->getVisual(), control
->getDepth(), ZPixmap
, 0, 0,
432 width
, height
, 32, 0);
435 fprintf(stderr
, "BImage::renderXImage: error creating XImage\n");
440 image
->data
= (char *) 0;
442 unsigned char *d
= new unsigned char[image
->bytes_per_line
* (height
+ 1)];
444 unsigned int o
= image
->bits_per_pixel
+
445 ((image
->byte_order
== MSBFirst
) ? 1 : 0);
447 bool unsupported
= False
;
449 if (control
->doDither() && width
> 1 && height
> 1) {
450 switch (control
->getVisual()->c_class
) {
452 TrueColorDither(o
, image
->bytes_per_line
, d
);
458 OrderedPseudoColorDither(image
->bytes_per_line
, d
);
460 PseudoColorDither(image
->bytes_per_line
, d
);
469 unsigned int x
, y
, r
, g
, b
, offset
;
470 unsigned char *pixel_data
= d
, *ppixel_data
= d
;
473 switch (control
->getVisual()->c_class
) {
476 for (y
= 0, offset
= 0; y
< height
; ++y
) {
477 for (x
= 0; x
< width
; ++x
, ++offset
) {
478 r
= red_table
[red
[offset
]];
479 g
= green_table
[green
[offset
]];
480 b
= blue_table
[blue
[offset
]];
482 pixel
= (r
* cpccpc
) + (g
* cpc
) + b
;
483 *pixel_data
++ = colors
[pixel
].pixel
;
486 pixel_data
= (ppixel_data
+= image
->bytes_per_line
);
492 for (y
= 0, offset
= 0; y
< height
; y
++) {
493 for (x
= 0; x
< width
; x
++, offset
++) {
494 r
= red_table
[red
[offset
]];
495 g
= green_table
[green
[offset
]];
496 b
= blue_table
[blue
[offset
]];
498 pixel
= (r
<< red_offset
) | (g
<< green_offset
) | (b
<< blue_offset
);
499 assignPixelData(o
, &pixel_data
, pixel
);
502 pixel_data
= (ppixel_data
+= image
->bytes_per_line
);
509 for (y
= 0, offset
= 0; y
< height
; y
++) {
510 for (x
= 0; x
< width
; x
++, offset
++) {
511 r
= *(red_table
+ *(red
+ offset
));
512 g
= *(green_table
+ *(green
+ offset
));
513 b
= *(blue_table
+ *(blue
+ offset
));
515 g
= ((r
* 30) + (g
* 59) + (b
* 11)) / 100;
516 *pixel_data
++ = colors
[g
].pixel
;
519 pixel_data
= (ppixel_data
+= image
->bytes_per_line
);
530 fprintf(stderr
, "BImage::renderXImage: unsupported visual\n");
532 XDestroyImage(image
);
536 image
->data
= (char *) d
;
542 Pixmap
BImage::renderPixmap(void) {
544 XCreatePixmap(control
->getBaseDisplay()->getXDisplay(),
545 control
->getDrawable(), width
, height
, control
->getDepth());
547 if (pixmap
== None
) {
548 fprintf(stderr
, "BImage::renderPixmap: error creating pixmap\n");
552 XImage
*image
= renderXImage();
555 XFreePixmap(control
->getBaseDisplay()->getXDisplay(), pixmap
);
560 XDestroyImage(image
);
561 XFreePixmap(control
->getBaseDisplay()->getXDisplay(), pixmap
);
565 XPutImage(control
->getBaseDisplay()->getXDisplay(), pixmap
,
566 DefaultGC(control
->getBaseDisplay()->getXDisplay(),
567 control
->getScreenInfo()->getScreenNumber()),
568 image
, 0, 0, 0, 0, width
, height
);
571 delete [] image
->data
;
575 XDestroyImage(image
);
581 void BImage::bevel1(void) {
582 if (width
> 2 && height
> 2) {
583 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
585 register unsigned char r
, g
, b
, rr
,gg
,bb
;
586 register unsigned int w
= width
, h
= height
- 1, wh
= w
* h
;
604 rr
= (r
>> 2) + (r
>> 1);
607 gg
= (g
>> 2) + (g
>> 1);
610 bb
= (b
>> 2) + (b
>> 1);
633 rr
= (r
>> 2) + (r
>> 1);
636 gg
= (g
>> 2) + (g
>> 1);
639 bb
= (b
>> 2) + (b
>> 1);
670 rr
= (r
>> 2) + (r
>> 1);
673 gg
= (g
>> 2) + (g
>> 1);
676 bb
= (b
>> 2) + (b
>> 1);
703 rr
= (r
>> 2) + (r
>> 1);
706 gg
= (g
>> 2) + (g
>> 1);
709 bb
= (b
>> 2) + (b
>> 1);
719 void BImage::bevel2(void) {
720 if (width
> 4 && height
> 4) {
721 unsigned char r
, g
, b
, rr
,gg
,bb
, *pr
= red
+ width
+ 1,
722 *pg
= green
+ width
+ 1, *pb
= blue
+ width
+ 1;
723 unsigned int w
= width
- 2, h
= height
- 1, wh
= width
* (height
- 3);
741 rr
= (r
>> 2) + (r
>> 1);
744 gg
= (g
>> 2) + (g
>> 1);
747 bb
= (b
>> 2) + (b
>> 1);
779 rr
= (r
>> 2) + (r
>> 1);
782 gg
= (g
>> 2) + (g
>> 1);
785 bb
= (b
>> 2) + (b
>> 1);
798 void BImage::border(const BTexture
&texture
) {
799 if (width
< 2 || height
< 2) return;
801 register unsigned int i
;
802 int r
= texture
.borderColor().red(),
803 g
= texture
.borderColor().green(),
804 b
= texture
.borderColor().blue();
806 unsigned char *pr
, *pg
, *pb
;
812 for (i
= 0; i
< width
; ++i
) {
819 // left and right lines (pr,pg,pb are already lined up)
820 for (i
= 1; i
< height
- 1; ++i
) {
833 // bottom line (pr,pg,pb are already lined up)
834 for (i
= 0; i
< width
; ++i
) {
842 void BImage::invert(void) {
843 register unsigned int i
, j
, wh
= (width
* height
) - 1;
846 for (i
= 0, j
= wh
; j
> i
; j
--, i
++) {
848 *(red
+ j
) = *(red
+ i
);
852 *(green
+ j
) = *(green
+ i
);
856 *(blue
+ j
) = *(blue
+ i
);
862 void BImage::dgradient(void) {
863 // diagonal gradient code was written by Mike Cole <mike@mydot.com>
864 // modified for interlacing by Brad Hughes
866 float drx
, dgx
, dbx
, dry
, dgy
, dby
, yr
= 0.0, yg
= 0.0, yb
= 0.0,
867 xr
= (float) from
.red(),
868 xg
= (float) from
.green(),
869 xb
= (float) from
.blue();
870 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
871 unsigned int w
= width
* 2, h
= height
* 2, *xt
= xtable
, *yt
= ytable
;
873 register unsigned int x
, y
;
875 dry
= drx
= (float) (to
.red() - from
.red());
876 dgy
= dgx
= (float) (to
.green() - from
.green());
877 dby
= dbx
= (float) (to
.blue() - from
.blue());
884 for (x
= 0; x
< width
; x
++) {
885 *(xt
++) = (unsigned char) (xr
);
886 *(xt
++) = (unsigned char) (xg
);
887 *(xt
++) = (unsigned char) (xb
);
899 for (y
= 0; y
< height
; y
++) {
900 *(yt
++) = ((unsigned char) yr
);
901 *(yt
++) = ((unsigned char) yg
);
902 *(yt
++) = ((unsigned char) yb
);
909 // Combine tables to create gradient
913 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
914 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
915 *(pr
++) = *(xt
++) + *(yt
);
916 *(pg
++) = *(xt
++) + *(yt
+ 1);
917 *(pb
++) = *(xt
++) + *(yt
+ 2);
921 // faked interlacing effect
922 unsigned char channel
, channel2
;
924 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
925 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
927 channel
= *(xt
++) + *(yt
);
928 channel2
= (channel
>> 1) + (channel
>> 2);
929 if (channel2
> channel
) channel2
= 0;
932 channel
= *(xt
++) + *(yt
+ 1);
933 channel2
= (channel
>> 1) + (channel
>> 2);
934 if (channel2
> channel
) channel2
= 0;
937 channel
= *(xt
++) + *(yt
+ 2);
938 channel2
= (channel
>> 1) + (channel
>> 2);
939 if (channel2
> channel
) channel2
= 0;
942 channel
= *(xt
++) + *(yt
);
943 channel2
= channel
+ (channel
>> 3);
944 if (channel2
< channel
) channel2
= ~0;
947 channel
= *(xt
++) + *(yt
+ 1);
948 channel2
= channel
+ (channel
>> 3);
949 if (channel2
< channel
) channel2
= ~0;
952 channel
= *(xt
++) + *(yt
+ 2);
953 channel2
= channel
+ (channel
>> 3);
954 if (channel2
< channel
) channel2
= ~0;
963 void BImage::hgradient(void) {
965 xr
= (float) from
.red(),
966 xg
= (float) from
.green(),
967 xb
= (float) from
.blue();
968 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
970 register unsigned int x
, y
;
972 drx
= (float) (to
.red() - from
.red());
973 dgx
= (float) (to
.green() - from
.green());
974 dbx
= (float) (to
.blue() - from
.blue());
980 if (interlaced
&& height
> 2) {
981 // faked interlacing effect
982 unsigned char channel
, channel2
;
984 for (x
= 0; x
< width
; x
++, pr
++, pg
++, pb
++) {
985 channel
= (unsigned char) xr
;
986 channel2
= (channel
>> 1) + (channel
>> 2);
987 if (channel2
> channel
) channel2
= 0;
990 channel
= (unsigned char) xg
;
991 channel2
= (channel
>> 1) + (channel
>> 2);
992 if (channel2
> channel
) channel2
= 0;
995 channel
= (unsigned char) xb
;
996 channel2
= (channel
>> 1) + (channel
>> 2);
997 if (channel2
> channel
) channel2
= 0;
1001 channel
= (unsigned char) xr
;
1002 channel2
= channel
+ (channel
>> 3);
1003 if (channel2
< channel
) channel2
= ~0;
1004 *(pr
+ width
) = channel2
;
1006 channel
= (unsigned char) xg
;
1007 channel2
= channel
+ (channel
>> 3);
1008 if (channel2
< channel
) channel2
= ~0;
1009 *(pg
+ width
) = channel2
;
1011 channel
= (unsigned char) xb
;
1012 channel2
= channel
+ (channel
>> 3);
1013 if (channel2
< channel
) channel2
= ~0;
1014 *(pb
+ width
) = channel2
;
1027 for (y
= 2; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1028 if (y
& 1) offset
= width
; else offset
= 0;
1030 memcpy(pr
, (red
+ offset
), width
);
1031 memcpy(pg
, (green
+ offset
), width
);
1032 memcpy(pb
, (blue
+ offset
), width
);
1036 for (x
= 0; x
< width
; x
++) {
1037 *(pr
++) = (unsigned char) (xr
);
1038 *(pg
++) = (unsigned char) (xg
);
1039 *(pb
++) = (unsigned char) (xb
);
1046 for (y
= 1; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1047 memcpy(pr
, red
, width
);
1048 memcpy(pg
, green
, width
);
1049 memcpy(pb
, blue
, width
);
1055 void BImage::vgradient(void) {
1056 float dry
, dgy
, dby
,
1057 yr
= (float) from
.red(),
1058 yg
= (float) from
.green(),
1059 yb
= (float) from
.blue();
1060 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1062 register unsigned int y
;
1064 dry
= (float) (to
.red() - from
.red());
1065 dgy
= (float) (to
.green() - from
.green());
1066 dby
= (float) (to
.blue() - from
.blue());
1073 // faked interlacing effect
1074 unsigned char channel
, channel2
;
1076 for (y
= 0; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1078 channel
= (unsigned char) yr
;
1079 channel2
= (channel
>> 1) + (channel
>> 2);
1080 if (channel2
> channel
) channel2
= 0;
1081 memset(pr
, channel2
, width
);
1083 channel
= (unsigned char) yg
;
1084 channel2
= (channel
>> 1) + (channel
>> 2);
1085 if (channel2
> channel
) channel2
= 0;
1086 memset(pg
, channel2
, width
);
1088 channel
= (unsigned char) yb
;
1089 channel2
= (channel
>> 1) + (channel
>> 2);
1090 if (channel2
> channel
) channel2
= 0;
1091 memset(pb
, channel2
, width
);
1093 channel
= (unsigned char) yr
;
1094 channel2
= channel
+ (channel
>> 3);
1095 if (channel2
< channel
) channel2
= ~0;
1096 memset(pr
, channel2
, width
);
1098 channel
= (unsigned char) yg
;
1099 channel2
= channel
+ (channel
>> 3);
1100 if (channel2
< channel
) channel2
= ~0;
1101 memset(pg
, channel2
, width
);
1103 channel
= (unsigned char) yb
;
1104 channel2
= channel
+ (channel
>> 3);
1105 if (channel2
< channel
) channel2
= ~0;
1106 memset(pb
, channel2
, width
);
1115 for (y
= 0; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1116 memset(pr
, (unsigned char) yr
, width
);
1117 memset(pg
, (unsigned char) yg
, width
);
1118 memset(pb
, (unsigned char) yb
, width
);
1128 void BImage::pgradient(void) {
1129 // pyramid gradient - based on original dgradient, written by
1130 // Mosfet (mosfet@kde.org)
1131 // adapted from kde sources for Blackbox by Brad Hughes
1133 float yr
, yg
, yb
, drx
, dgx
, dbx
, dry
, dgy
, dby
,
1135 int rsign
, gsign
, bsign
;
1136 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1137 unsigned int tr
= to
.red(), tg
= to
.green(), tb
= to
.blue(),
1138 *xt
= xtable
, *yt
= ytable
;
1140 register unsigned int x
, y
;
1142 dry
= drx
= (float) (to
.red() - from
.red());
1143 dgy
= dgx
= (float) (to
.green() - from
.green());
1144 dby
= dbx
= (float) (to
.blue() - from
.blue());
1146 rsign
= (drx
< 0) ? -1 : 1;
1147 gsign
= (dgx
< 0) ? -1 : 1;
1148 bsign
= (dbx
< 0) ? -1 : 1;
1150 xr
= yr
= (drx
/ 2);
1151 xg
= yg
= (dgx
/ 2);
1152 xb
= yb
= (dbx
/ 2);
1159 for (x
= 0; x
< width
; x
++) {
1160 *(xt
++) = (unsigned char) ((xr
< 0) ? -xr
: xr
);
1161 *(xt
++) = (unsigned char) ((xg
< 0) ? -xg
: xg
);
1162 *(xt
++) = (unsigned char) ((xb
< 0) ? -xb
: xb
);
1174 for (y
= 0; y
< height
; y
++) {
1175 *(yt
++) = ((unsigned char) ((yr
< 0) ? -yr
: yr
));
1176 *(yt
++) = ((unsigned char) ((yg
< 0) ? -yg
: yg
));
1177 *(yt
++) = ((unsigned char) ((yb
< 0) ? -yb
: yb
));
1184 // Combine tables to create gradient
1188 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1189 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1190 *(pr
++) = (unsigned char) (tr
- (rsign
* (*(xt
++) + *(yt
))));
1191 *(pg
++) = (unsigned char) (tg
- (gsign
* (*(xt
++) + *(yt
+ 1))));
1192 *(pb
++) = (unsigned char) (tb
- (bsign
* (*(xt
++) + *(yt
+ 2))));
1196 // faked interlacing effect
1197 unsigned char channel
, channel2
;
1199 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1200 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1202 channel
= (unsigned char) (tr
- (rsign
* (*(xt
++) + *(yt
))));
1203 channel2
= (channel
>> 1) + (channel
>> 2);
1204 if (channel2
> channel
) channel2
= 0;
1207 channel
= (unsigned char) (tg
- (gsign
* (*(xt
++) + *(yt
+ 1))));
1208 channel2
= (channel
>> 1) + (channel
>> 2);
1209 if (channel2
> channel
) channel2
= 0;
1212 channel
= (unsigned char) (tb
- (bsign
* (*(xt
++) + *(yt
+ 2))));
1213 channel2
= (channel
>> 1) + (channel
>> 2);
1214 if (channel2
> channel
) channel2
= 0;
1217 channel
= (unsigned char) (tr
- (rsign
* (*(xt
++) + *(yt
))));
1218 channel2
= channel
+ (channel
>> 3);
1219 if (channel2
< channel
) channel2
= ~0;
1222 channel
= (unsigned char) (tg
- (gsign
* (*(xt
++) + *(yt
+ 1))));
1223 channel2
= channel
+ (channel
>> 3);
1224 if (channel2
< channel
) channel2
= ~0;
1227 channel
= (unsigned char) (tb
- (bsign
* (*(xt
++) + *(yt
+ 2))));
1228 channel2
= channel
+ (channel
>> 3);
1229 if (channel2
< channel
) channel2
= ~0;
1238 void BImage::rgradient(void) {
1239 // rectangle gradient - based on original dgradient, written by
1240 // Mosfet (mosfet@kde.org)
1241 // adapted from kde sources for Blackbox by Brad Hughes
1243 float drx
, dgx
, dbx
, dry
, dgy
, dby
, xr
, xg
, xb
, yr
, yg
, yb
;
1244 int rsign
, gsign
, bsign
;
1245 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1246 unsigned int tr
= to
.red(), tg
= to
.green(), tb
= to
.blue(),
1247 *xt
= xtable
, *yt
= ytable
;
1249 register unsigned int x
, y
;
1251 dry
= drx
= (float) (to
.red() - from
.red());
1252 dgy
= dgx
= (float) (to
.green() - from
.green());
1253 dby
= dbx
= (float) (to
.blue() - from
.blue());
1255 rsign
= (drx
< 0) ? -2 : 2;
1256 gsign
= (dgx
< 0) ? -2 : 2;
1257 bsign
= (dbx
< 0) ? -2 : 2;
1259 xr
= yr
= (drx
/ 2);
1260 xg
= yg
= (dgx
/ 2);
1261 xb
= yb
= (dbx
/ 2);
1268 for (x
= 0; x
< width
; x
++) {
1269 *(xt
++) = (unsigned char) ((xr
< 0) ? -xr
: xr
);
1270 *(xt
++) = (unsigned char) ((xg
< 0) ? -xg
: xg
);
1271 *(xt
++) = (unsigned char) ((xb
< 0) ? -xb
: xb
);
1283 for (y
= 0; y
< height
; y
++) {
1284 *(yt
++) = ((unsigned char) ((yr
< 0) ? -yr
: yr
));
1285 *(yt
++) = ((unsigned char) ((yg
< 0) ? -yg
: yg
));
1286 *(yt
++) = ((unsigned char) ((yb
< 0) ? -yb
: yb
));
1293 // Combine tables to create gradient
1297 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1298 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1299 *(pr
++) = (unsigned char) (tr
- (rsign
* max(*(xt
++), *(yt
))));
1300 *(pg
++) = (unsigned char) (tg
- (gsign
* max(*(xt
++), *(yt
+ 1))));
1301 *(pb
++) = (unsigned char) (tb
- (bsign
* max(*(xt
++), *(yt
+ 2))));
1305 // faked interlacing effect
1306 unsigned char channel
, channel2
;
1308 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1309 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1311 channel
= (unsigned char) (tr
- (rsign
* max(*(xt
++), *(yt
))));
1312 channel2
= (channel
>> 1) + (channel
>> 2);
1313 if (channel2
> channel
) channel2
= 0;
1316 channel
= (unsigned char) (tg
- (gsign
* max(*(xt
++), *(yt
+ 1))));
1317 channel2
= (channel
>> 1) + (channel
>> 2);
1318 if (channel2
> channel
) channel2
= 0;
1321 channel
= (unsigned char) (tb
- (bsign
* max(*(xt
++), *(yt
+ 2))));
1322 channel2
= (channel
>> 1) + (channel
>> 2);
1323 if (channel2
> channel
) channel2
= 0;
1326 channel
= (unsigned char) (tr
- (rsign
* max(*(xt
++), *(yt
))));
1327 channel2
= channel
+ (channel
>> 3);
1328 if (channel2
< channel
) channel2
= ~0;
1331 channel
= (unsigned char) (tg
- (gsign
* max(*(xt
++), *(yt
+ 1))));
1332 channel2
= channel
+ (channel
>> 3);
1333 if (channel2
< channel
) channel2
= ~0;
1336 channel
= (unsigned char) (tb
- (bsign
* max(*(xt
++), *(yt
+ 2))));
1337 channel2
= channel
+ (channel
>> 3);
1338 if (channel2
< channel
) channel2
= ~0;
1347 void BImage::egradient(void) {
1348 // elliptic gradient - based on original dgradient, written by
1349 // Mosfet (mosfet@kde.org)
1350 // adapted from kde sources for Blackbox by Brad Hughes
1352 float drx
, dgx
, dbx
, dry
, dgy
, dby
, yr
, yg
, yb
, xr
, xg
, xb
;
1353 int rsign
, gsign
, bsign
;
1354 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1355 unsigned int *xt
= xtable
, *yt
= ytable
,
1356 tr
= (unsigned long) to
.red(),
1357 tg
= (unsigned long) to
.green(),
1358 tb
= (unsigned long) to
.blue();
1360 register unsigned int x
, y
;
1362 dry
= drx
= (float) (to
.red() - from
.red());
1363 dgy
= dgx
= (float) (to
.green() - from
.green());
1364 dby
= dbx
= (float) (to
.blue() - from
.blue());
1366 rsign
= (drx
< 0) ? -1 : 1;
1367 gsign
= (dgx
< 0) ? -1 : 1;
1368 bsign
= (dbx
< 0) ? -1 : 1;
1370 xr
= yr
= (drx
/ 2);
1371 xg
= yg
= (dgx
/ 2);
1372 xb
= yb
= (dbx
/ 2);
1379 for (x
= 0; x
< width
; x
++) {
1380 *(xt
++) = (unsigned long) (xr
* xr
);
1381 *(xt
++) = (unsigned long) (xg
* xg
);
1382 *(xt
++) = (unsigned long) (xb
* xb
);
1394 for (y
= 0; y
< height
; y
++) {
1395 *(yt
++) = (unsigned long) (yr
* yr
);
1396 *(yt
++) = (unsigned long) (yg
* yg
);
1397 *(yt
++) = (unsigned long) (yb
* yb
);
1404 // Combine tables to create gradient
1408 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1409 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1410 *(pr
++) = (unsigned char)
1411 (tr
- (rsign
* control
->getSqrt(*(xt
++) + *(yt
))));
1412 *(pg
++) = (unsigned char)
1413 (tg
- (gsign
* control
->getSqrt(*(xt
++) + *(yt
+ 1))));
1414 *(pb
++) = (unsigned char)
1415 (tb
- (bsign
* control
->getSqrt(*(xt
++) + *(yt
+ 2))));
1419 // faked interlacing effect
1420 unsigned char channel
, channel2
;
1422 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1423 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1425 channel
= (unsigned char)
1426 (tr
- (rsign
* control
->getSqrt(*(xt
++) + *(yt
))));
1427 channel2
= (channel
>> 1) + (channel
>> 2);
1428 if (channel2
> channel
) channel2
= 0;
1431 channel
= (unsigned char)
1432 (tg
- (gsign
* control
->getSqrt(*(xt
++) + *(yt
+ 1))));
1433 channel2
= (channel
>> 1) + (channel
>> 2);
1434 if (channel2
> channel
) channel2
= 0;
1437 channel
= (unsigned char)
1438 (tb
- (bsign
* control
->getSqrt(*(xt
++) + *(yt
+ 2))));
1439 channel2
= (channel
>> 1) + (channel
>> 2);
1440 if (channel2
> channel
) channel2
= 0;
1443 channel
= (unsigned char)
1444 (tr
- (rsign
* control
->getSqrt(*(xt
++) + *(yt
))));
1445 channel2
= channel
+ (channel
>> 3);
1446 if (channel2
< channel
) channel2
= ~0;
1449 channel
= (unsigned char)
1450 (tg
- (gsign
* control
->getSqrt(*(xt
++) + *(yt
+ 1))));
1451 channel2
= channel
+ (channel
>> 3);
1452 if (channel2
< channel
) channel2
= ~0;
1455 channel
= (unsigned char)
1456 (tb
- (bsign
* control
->getSqrt(*(xt
++) + *(yt
+ 2))));
1457 channel2
= channel
+ (channel
>> 3);
1458 if (channel2
< channel
) channel2
= ~0;
1467 void BImage::pcgradient(void) {
1468 // pipe cross gradient - based on original dgradient, written by
1469 // Mosfet (mosfet@kde.org)
1470 // adapted from kde sources for Blackbox by Brad Hughes
1472 float drx
, dgx
, dbx
, dry
, dgy
, dby
, xr
, xg
, xb
, yr
, yg
, yb
;
1473 int rsign
, gsign
, bsign
;
1474 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1475 unsigned int *xt
= xtable
, *yt
= ytable
,
1480 register unsigned int x
, y
;
1482 dry
= drx
= (float) (to
.red() - from
.red());
1483 dgy
= dgx
= (float) (to
.green() - from
.green());
1484 dby
= dbx
= (float) (to
.blue() - from
.blue());
1486 rsign
= (drx
< 0) ? -2 : 2;
1487 gsign
= (dgx
< 0) ? -2 : 2;
1488 bsign
= (dbx
< 0) ? -2 : 2;
1490 xr
= yr
= (drx
/ 2);
1491 xg
= yg
= (dgx
/ 2);
1492 xb
= yb
= (dbx
/ 2);
1499 for (x
= 0; x
< width
; x
++) {
1500 *(xt
++) = (unsigned char) ((xr
< 0) ? -xr
: xr
);
1501 *(xt
++) = (unsigned char) ((xg
< 0) ? -xg
: xg
);
1502 *(xt
++) = (unsigned char) ((xb
< 0) ? -xb
: xb
);
1514 for (y
= 0; y
< height
; y
++) {
1515 *(yt
++) = ((unsigned char) ((yr
< 0) ? -yr
: yr
));
1516 *(yt
++) = ((unsigned char) ((yg
< 0) ? -yg
: yg
));
1517 *(yt
++) = ((unsigned char) ((yb
< 0) ? -yb
: yb
));
1524 // Combine tables to create gradient
1527 // normal pcgradient
1528 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1529 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1530 *(pr
++) = (unsigned char) (tr
- (rsign
* min(*(xt
++), *(yt
))));
1531 *(pg
++) = (unsigned char) (tg
- (gsign
* min(*(xt
++), *(yt
+ 1))));
1532 *(pb
++) = (unsigned char) (tb
- (bsign
* min(*(xt
++), *(yt
+ 2))));
1536 // faked interlacing effect
1537 unsigned char channel
, channel2
;
1539 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1540 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1542 channel
= (unsigned char) (tr
- (rsign
* min(*(xt
++), *(yt
))));
1543 channel2
= (channel
>> 1) + (channel
>> 2);
1544 if (channel2
> channel
) channel2
= 0;
1547 channel
= (unsigned char) (tg
- (bsign
* min(*(xt
++), *(yt
+ 1))));
1548 channel2
= (channel
>> 1) + (channel
>> 2);
1549 if (channel2
> channel
) channel2
= 0;
1552 channel
= (unsigned char) (tb
- (gsign
* min(*(xt
++), *(yt
+ 2))));
1553 channel2
= (channel
>> 1) + (channel
>> 2);
1554 if (channel2
> channel
) channel2
= 0;
1557 channel
= (unsigned char) (tr
- (rsign
* min(*(xt
++), *(yt
))));
1558 channel2
= channel
+ (channel
>> 3);
1559 if (channel2
< channel
) channel2
= ~0;
1562 channel
= (unsigned char) (tg
- (gsign
* min(*(xt
++), *(yt
+ 1))));
1563 channel2
= channel
+ (channel
>> 3);
1564 if (channel2
< channel
) channel2
= ~0;
1567 channel
= (unsigned char) (tb
- (bsign
* min(*(xt
++), *(yt
+ 2))));
1568 channel2
= channel
+ (channel
>> 3);
1569 if (channel2
< channel
) channel2
= ~0;
1578 void BImage::cdgradient(void) {
1579 // cross diagonal gradient - based on original dgradient, written by
1580 // Mosfet (mosfet@kde.org)
1581 // adapted from kde sources for Blackbox by Brad Hughes
1583 float drx
, dgx
, dbx
, dry
, dgy
, dby
, yr
= 0.0, yg
= 0.0, yb
= 0.0,
1584 xr
= (float) from
.red(),
1585 xg
= (float) from
.green(),
1586 xb
= (float) from
.blue();
1587 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1588 unsigned int w
= width
* 2, h
= height
* 2, *xt
, *yt
;
1590 register unsigned int x
, y
;
1592 dry
= drx
= (float) (to
.red() - from
.red());
1593 dgy
= dgx
= (float) (to
.green() - from
.green());
1594 dby
= dbx
= (float) (to
.blue() - from
.blue());
1601 for (xt
= (xtable
+ (width
* 3) - 1), x
= 0; x
< width
; x
++) {
1602 *(xt
--) = (unsigned char) xb
;
1603 *(xt
--) = (unsigned char) xg
;
1604 *(xt
--) = (unsigned char) xr
;
1616 for (yt
= ytable
, y
= 0; y
< height
; y
++) {
1617 *(yt
++) = (unsigned char) yr
;
1618 *(yt
++) = (unsigned char) yg
;
1619 *(yt
++) = (unsigned char) yb
;
1626 // Combine tables to create gradient
1629 // normal cdgradient
1630 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1631 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1632 *(pr
++) = *(xt
++) + *(yt
);
1633 *(pg
++) = *(xt
++) + *(yt
+ 1);
1634 *(pb
++) = *(xt
++) + *(yt
+ 2);
1638 // faked interlacing effect
1639 unsigned char channel
, channel2
;
1641 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1642 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1644 channel
= *(xt
++) + *(yt
);
1645 channel2
= (channel
>> 1) + (channel
>> 2);
1646 if (channel2
> channel
) channel2
= 0;
1649 channel
= *(xt
++) + *(yt
+ 1);
1650 channel2
= (channel
>> 1) + (channel
>> 2);
1651 if (channel2
> channel
) channel2
= 0;
1654 channel
= *(xt
++) + *(yt
+ 2);
1655 channel2
= (channel
>> 1) + (channel
>> 2);
1656 if (channel2
> channel
) channel2
= 0;
1659 channel
= *(xt
++) + *(yt
);
1660 channel2
= channel
+ (channel
>> 3);
1661 if (channel2
< channel
) channel2
= ~0;
1664 channel
= *(xt
++) + *(yt
+ 1);
1665 channel2
= channel
+ (channel
>> 3);
1666 if (channel2
< channel
) channel2
= ~0;
1669 channel
= *(xt
++) + *(yt
+ 2);
1670 channel2
= channel
+ (channel
>> 3);
1671 if (channel2
< channel
) channel2
= ~0;
This page took 0.108036 seconds and 4 git commands to generate.