]>
Dogcows Code - chaz/openbox/blob - otk/image.cc
1 // -*- mode: C++; indent-tabs-mode: nil; -*-
4 # include "../config.h"
5 #endif // HAVE_CONFIG_H
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(OBDisplay::display
,
66 control
->getDrawable(), width
,
67 height
, control
->getDepth());
69 fprintf(stderr
, "BImage::render_solid: error creating pixmap\n");
73 BPen
pen(texture
.color());
74 BPen
penlight(texture
.lightColor());
75 BPen
penshadow(texture
.shadowColor());
77 XFillRectangle(OBDisplay::display
, pixmap
, pen
.gc(), 0, 0, width
, height
);
79 if (texture
.texture() & BTexture::Interlaced
) {
80 BPen
peninterlace(texture
.colorTo());
81 for (unsigned int i
= 0; i
< height
; i
+= 2)
82 XDrawLine(OBDisplay::display
, pixmap
, peninterlace
.gc(), 0, i
, width
, i
);
85 int left
= 0, top
= 0, right
= width
- 1, bottom
= height
- 1;
87 if (texture
.texture() & BTexture::Border
) {
88 BPen
penborder(texture
.borderColor());
89 XDrawRectangle(OBDisplay::display
, pixmap
, penborder
.gc(),
90 left
, top
, right
, bottom
);
93 if (texture
.texture() & BTexture::Bevel1
) {
94 if (texture
.texture() & BTexture::Raised
) {
95 XDrawLine(OBDisplay::display
, pixmap
, penshadow
.gc(),
96 left
, bottom
, right
, bottom
);
97 XDrawLine(OBDisplay::display
, pixmap
, penshadow
.gc(),
98 right
, bottom
, right
, top
);
100 XDrawLine(OBDisplay::display
, pixmap
, penlight
.gc(),
101 left
, top
, right
, top
);
102 XDrawLine(OBDisplay::display
, pixmap
, penlight
.gc(),
103 left
, bottom
, left
, top
);
104 } else if (texture
.texture() & BTexture::Sunken
) {
105 XDrawLine(OBDisplay::display
, pixmap
, penlight
.gc(),
106 left
, bottom
, right
, bottom
);
107 XDrawLine(OBDisplay::display
, pixmap
, penlight
.gc(),
108 right
, bottom
, right
, top
);
110 XDrawLine(OBDisplay::display
, pixmap
, penshadow
.gc(),
111 left
, top
, right
, top
);
112 XDrawLine(OBDisplay::display
, pixmap
, penshadow
.gc(),
113 left
, bottom
, left
, top
);
115 } else if (texture
.texture() & BTexture::Bevel2
) {
116 if (texture
.texture() & BTexture::Raised
) {
117 XDrawLine(OBDisplay::display
, pixmap
, penshadow
.gc(),
118 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
119 XDrawLine(OBDisplay::display
, pixmap
, penshadow
.gc(),
120 right
- 2, bottom
- 2, right
- 2, top
+ 1);
122 XDrawLine(OBDisplay::display
, pixmap
, penlight
.gc(),
123 left
+ 1, top
+ 1, right
- 2, top
+ 1);
124 XDrawLine(OBDisplay::display
, pixmap
, penlight
.gc(),
125 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
126 } else if (texture
.texture() & BTexture::Sunken
) {
127 XDrawLine(OBDisplay::display
, pixmap
, penlight
.gc(),
128 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
129 XDrawLine(OBDisplay::display
, pixmap
, penlight
.gc(),
130 right
- 2, bottom
- 2, right
- 2, top
+ 1);
132 XDrawLine(OBDisplay::display
, pixmap
, penshadow
.gc(),
133 left
+ 1, top
+ 1, right
- 2, top
+ 1);
134 XDrawLine(OBDisplay::display
, pixmap
, penshadow
.gc(),
135 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
143 Pixmap
BImage::render_gradient(const BTexture
&texture
) {
144 bool inverted
= False
;
146 interlaced
= texture
.texture() & BTexture::Interlaced
;
148 if (texture
.texture() & BTexture::Sunken
) {
149 from
= texture
.colorTo();
150 to
= texture
.color();
152 if (! (texture
.texture() & BTexture::Invert
)) inverted
= True
;
154 from
= texture
.color();
155 to
= texture
.colorTo();
157 if (texture
.texture() & BTexture::Invert
) inverted
= True
;
160 control
->getGradientBuffers(width
, height
, &xtable
, &ytable
);
162 if (texture
.texture() & BTexture::Diagonal
) dgradient();
163 else if (texture
.texture() & BTexture::Elliptic
) egradient();
164 else if (texture
.texture() & BTexture::Horizontal
) hgradient();
165 else if (texture
.texture() & BTexture::Pyramid
) pgradient();
166 else if (texture
.texture() & BTexture::Rectangle
) rgradient();
167 else if (texture
.texture() & BTexture::Vertical
) vgradient();
168 else if (texture
.texture() & BTexture::CrossDiagonal
) cdgradient();
169 else if (texture
.texture() & BTexture::PipeCross
) pcgradient();
171 if (texture
.texture() & BTexture::Bevel1
) bevel1();
172 else if (texture
.texture() & BTexture::Bevel2
) bevel2();
174 if (texture
.texture() & BTexture::Border
) border(texture
);
176 if (inverted
) invert();
178 return renderPixmap();
183 static const unsigned char dither4
[4][4] = {
192 * Helper function for TrueColorDither and renderXImage
194 * This handles the proper setting of the image data based on the image depth
195 * and the machine's byte ordering
198 void assignPixelData(unsigned int bit_depth
, unsigned char **data
,
199 unsigned long pixel
) {
200 unsigned char *pixel_data
= *data
;
203 *pixel_data
++ = pixel
;
206 case 16: // 16bpp LSB
207 *pixel_data
++ = pixel
;
208 *pixel_data
++ = pixel
>> 8;
211 case 17: // 16bpp MSB
212 *pixel_data
++ = pixel
>> 8;
213 *pixel_data
++ = pixel
;
216 case 24: // 24bpp LSB
217 *pixel_data
++ = pixel
;
218 *pixel_data
++ = pixel
>> 8;
219 *pixel_data
++ = pixel
>> 16;
222 case 25: // 24bpp MSB
223 *pixel_data
++ = pixel
>> 16;
224 *pixel_data
++ = pixel
>> 8;
225 *pixel_data
++ = pixel
;
228 case 32: // 32bpp LSB
229 *pixel_data
++ = pixel
;
230 *pixel_data
++ = pixel
>> 8;
231 *pixel_data
++ = pixel
>> 16;
232 *pixel_data
++ = pixel
>> 24;
235 case 33: // 32bpp MSB
236 *pixel_data
++ = pixel
>> 24;
237 *pixel_data
++ = pixel
>> 16;
238 *pixel_data
++ = pixel
>> 8;
239 *pixel_data
++ = pixel
;
242 *data
= pixel_data
; // assign back so we don't lose our place
246 // algorithm: ordered dithering... many many thanks to rasterman
247 // (raster@rasterman.com) for telling me about this... portions of this
248 // code is based off of his code in Imlib
249 void BImage::TrueColorDither(unsigned int bit_depth
, int bytes_per_line
,
250 unsigned char *pixel_data
) {
251 unsigned int x
, y
, dithx
, dithy
, r
, g
, b
, er
, eg
, eb
, offset
;
252 unsigned char *ppixel_data
= pixel_data
;
255 for (y
= 0, offset
= 0; y
< height
; y
++) {
258 for (x
= 0; x
< width
; x
++, offset
++) {
264 er
= r
& (red_bits
- 1);
265 eg
= g
& (green_bits
- 1);
266 eb
= b
& (blue_bits
- 1);
272 if ((dither4
[dithy
][dithx
] < er
) && (r
< red_table
[255])) r
++;
273 if ((dither4
[dithy
][dithx
] < eg
) && (g
< green_table
[255])) g
++;
274 if ((dither4
[dithy
][dithx
] < eb
) && (b
< blue_table
[255])) b
++;
276 pixel
= (r
<< red_offset
) | (g
<< green_offset
) | (b
<< blue_offset
);
277 assignPixelData(bit_depth
, &pixel_data
, pixel
);
280 pixel_data
= (ppixel_data
+= bytes_per_line
);
285 const static unsigned char dither8
[8][8] = {
286 { 0, 32, 8, 40, 2, 34, 10, 42},
287 { 48, 16, 56, 24, 50, 18, 58, 26},
288 { 12, 44, 4, 36, 14, 46, 6, 38},
289 { 60, 28, 52, 20, 62, 30, 54, 22},
290 { 3, 35, 11, 43, 1, 33, 9, 41},
291 { 51, 19, 59, 27, 49, 17, 57, 25},
292 { 15, 47, 7, 39, 13, 45, 5, 37},
293 { 63, 31, 55, 23, 61, 29, 53, 21}
296 void BImage::OrderedPseudoColorDither(int bytes_per_line
,
297 unsigned char *pixel_data
) {
298 unsigned int x
, y
, dithx
, dithy
, r
, g
, b
, er
, eg
, eb
, offset
;
300 unsigned char *ppixel_data
= pixel_data
;
302 for (y
= 0, offset
= 0; y
< height
; y
++) {
305 for (x
= 0; x
< width
; x
++, offset
++) {
312 er
= r
& (red_bits
- 1);
313 eg
= g
& (green_bits
- 1);
314 eb
= b
& (blue_bits
- 1);
320 if ((dither8
[dithy
][dithx
] < er
) && (r
< red_table
[255])) r
++;
321 if ((dither8
[dithy
][dithx
] < eg
) && (g
< green_table
[255])) g
++;
322 if ((dither8
[dithy
][dithx
] < eb
) && (b
< blue_table
[255])) b
++;
324 pixel
= (r
* cpccpc
) + (g
* cpc
) + b
;
325 *(pixel_data
++) = colors
[pixel
].pixel
;
328 pixel_data
= (ppixel_data
+= bytes_per_line
);
333 void BImage::PseudoColorDither(int bytes_per_line
, unsigned char *pixel_data
) {
335 *rerr
= new short[width
+ 2],
336 *gerr
= new short[width
+ 2],
337 *berr
= new short[width
+ 2],
338 *nrerr
= new short[width
+ 2],
339 *ngerr
= new short[width
+ 2],
340 *nberr
= new short[width
+ 2];
342 int rr
, gg
, bb
, rer
, ger
, ber
;
343 int dd
= 255 / control
->getColorsPerChannel();
344 unsigned int x
, y
, r
, g
, b
, offset
;
346 unsigned char *ppixel_data
= pixel_data
;
348 for (x
= 0; x
< width
; x
++) {
349 *(rerr
+ x
) = *(red
+ x
);
350 *(gerr
+ x
) = *(green
+ x
);
351 *(berr
+ x
) = *(blue
+ x
);
354 *(rerr
+ x
) = *(gerr
+ x
) = *(berr
+ x
) = 0;
356 for (y
= 0, offset
= 0; y
< height
; y
++) {
357 if (y
< (height
- 1)) {
358 int i
= offset
+ width
;
359 for (x
= 0; x
< width
; x
++, i
++) {
360 *(nrerr
+ x
) = *(red
+ i
);
361 *(ngerr
+ x
) = *(green
+ i
);
362 *(nberr
+ x
) = *(blue
+ i
);
365 *(nrerr
+ x
) = *(red
+ (--i
));
366 *(ngerr
+ x
) = *(green
+ i
);
367 *(nberr
+ x
) = *(blue
+ i
);
370 for (x
= 0; x
< width
; x
++) {
375 if (rr
> 255) rr
= 255; else if (rr
< 0) rr
= 0;
376 if (gg
> 255) gg
= 255; else if (gg
< 0) gg
= 0;
377 if (bb
> 255) bb
= 255; else if (bb
< 0) bb
= 0;
383 rer
= rerr
[x
] - r
*dd
;
384 ger
= gerr
[x
] - g
*dd
;
385 ber
= berr
[x
] - b
*dd
;
387 pixel
= (r
* cpccpc
) + (g
* cpc
) + b
;
388 *pixel_data
++ = colors
[pixel
].pixel
;
403 pixel_data
= (ppixel_data
+= bytes_per_line
);
426 XImage
*BImage::renderXImage(void) {
428 XCreateImage(OBDisplay::display
,
429 control
->getVisual(), control
->getDepth(), ZPixmap
, 0, 0,
430 width
, height
, 32, 0);
433 fprintf(stderr
, "BImage::renderXImage: error creating XImage\n");
438 image
->data
= (char *) 0;
440 unsigned char *d
= new unsigned char[image
->bytes_per_line
* (height
+ 1)];
442 unsigned int o
= image
->bits_per_pixel
+
443 ((image
->byte_order
== MSBFirst
) ? 1 : 0);
445 bool unsupported
= False
;
447 if (control
->doDither() && width
> 1 && height
> 1) {
448 switch (control
->getVisual()->c_class
) {
450 TrueColorDither(o
, image
->bytes_per_line
, d
);
456 OrderedPseudoColorDither(image
->bytes_per_line
, d
);
458 PseudoColorDither(image
->bytes_per_line
, d
);
467 unsigned int x
, y
, r
, g
, b
, offset
;
468 unsigned char *pixel_data
= d
, *ppixel_data
= d
;
471 switch (control
->getVisual()->c_class
) {
474 for (y
= 0, offset
= 0; y
< height
; ++y
) {
475 for (x
= 0; x
< width
; ++x
, ++offset
) {
476 r
= red_table
[red
[offset
]];
477 g
= green_table
[green
[offset
]];
478 b
= blue_table
[blue
[offset
]];
480 pixel
= (r
* cpccpc
) + (g
* cpc
) + b
;
481 *pixel_data
++ = colors
[pixel
].pixel
;
484 pixel_data
= (ppixel_data
+= image
->bytes_per_line
);
490 for (y
= 0, offset
= 0; y
< height
; y
++) {
491 for (x
= 0; x
< width
; x
++, offset
++) {
492 r
= red_table
[red
[offset
]];
493 g
= green_table
[green
[offset
]];
494 b
= blue_table
[blue
[offset
]];
496 pixel
= (r
<< red_offset
) | (g
<< green_offset
) | (b
<< blue_offset
);
497 assignPixelData(o
, &pixel_data
, pixel
);
500 pixel_data
= (ppixel_data
+= image
->bytes_per_line
);
507 for (y
= 0, offset
= 0; y
< height
; y
++) {
508 for (x
= 0; x
< width
; x
++, offset
++) {
509 r
= *(red_table
+ *(red
+ offset
));
510 g
= *(green_table
+ *(green
+ offset
));
511 b
= *(blue_table
+ *(blue
+ offset
));
513 g
= ((r
* 30) + (g
* 59) + (b
* 11)) / 100;
514 *pixel_data
++ = colors
[g
].pixel
;
517 pixel_data
= (ppixel_data
+= image
->bytes_per_line
);
528 fprintf(stderr
, "BImage::renderXImage: unsupported visual\n");
530 XDestroyImage(image
);
534 image
->data
= (char *) d
;
540 Pixmap
BImage::renderPixmap(void) {
542 XCreatePixmap(OBDisplay::display
,
543 control
->getDrawable(), width
, height
, control
->getDepth());
545 if (pixmap
== None
) {
546 fprintf(stderr
, "BImage::renderPixmap: error creating pixmap\n");
550 XImage
*image
= renderXImage();
553 XFreePixmap(OBDisplay::display
, pixmap
);
558 XDestroyImage(image
);
559 XFreePixmap(OBDisplay::display
, pixmap
);
563 XPutImage(OBDisplay::display
, pixmap
,
564 DefaultGC(OBDisplay::display
,
565 control
->getScreenInfo()->getScreenNumber()),
566 image
, 0, 0, 0, 0, width
, height
);
569 delete [] image
->data
;
573 XDestroyImage(image
);
579 void BImage::bevel1(void) {
580 if (width
> 2 && height
> 2) {
581 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
583 register unsigned char r
, g
, b
, rr
,gg
,bb
;
584 register unsigned int w
= width
, h
= height
- 1, wh
= w
* h
;
602 rr
= (r
>> 2) + (r
>> 1);
605 gg
= (g
>> 2) + (g
>> 1);
608 bb
= (b
>> 2) + (b
>> 1);
631 rr
= (r
>> 2) + (r
>> 1);
634 gg
= (g
>> 2) + (g
>> 1);
637 bb
= (b
>> 2) + (b
>> 1);
668 rr
= (r
>> 2) + (r
>> 1);
671 gg
= (g
>> 2) + (g
>> 1);
674 bb
= (b
>> 2) + (b
>> 1);
701 rr
= (r
>> 2) + (r
>> 1);
704 gg
= (g
>> 2) + (g
>> 1);
707 bb
= (b
>> 2) + (b
>> 1);
717 void BImage::bevel2(void) {
718 if (width
> 4 && height
> 4) {
719 unsigned char r
, g
, b
, rr
,gg
,bb
, *pr
= red
+ width
+ 1,
720 *pg
= green
+ width
+ 1, *pb
= blue
+ width
+ 1;
721 unsigned int w
= width
- 2, h
= height
- 1, wh
= width
* (height
- 3);
739 rr
= (r
>> 2) + (r
>> 1);
742 gg
= (g
>> 2) + (g
>> 1);
745 bb
= (b
>> 2) + (b
>> 1);
777 rr
= (r
>> 2) + (r
>> 1);
780 gg
= (g
>> 2) + (g
>> 1);
783 bb
= (b
>> 2) + (b
>> 1);
796 void BImage::border(const BTexture
&texture
) {
797 if (width
< 2 || height
< 2) return;
799 register unsigned int i
;
800 int r
= texture
.borderColor().red(),
801 g
= texture
.borderColor().green(),
802 b
= texture
.borderColor().blue();
804 unsigned char *pr
, *pg
, *pb
;
810 for (i
= 0; i
< width
; ++i
) {
817 // left and right lines (pr,pg,pb are already lined up)
818 for (i
= 1; i
< height
- 1; ++i
) {
831 // bottom line (pr,pg,pb are already lined up)
832 for (i
= 0; i
< width
; ++i
) {
840 void BImage::invert(void) {
841 register unsigned int i
, j
, wh
= (width
* height
) - 1;
844 for (i
= 0, j
= wh
; j
> i
; j
--, i
++) {
846 *(red
+ j
) = *(red
+ i
);
850 *(green
+ j
) = *(green
+ i
);
854 *(blue
+ j
) = *(blue
+ i
);
860 void BImage::dgradient(void) {
861 // diagonal gradient code was written by Mike Cole <mike@mydot.com>
862 // modified for interlacing by Brad Hughes
864 float drx
, dgx
, dbx
, dry
, dgy
, dby
, yr
= 0.0, yg
= 0.0, yb
= 0.0,
865 xr
= (float) from
.red(),
866 xg
= (float) from
.green(),
867 xb
= (float) from
.blue();
868 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
869 unsigned int w
= width
* 2, h
= height
* 2, *xt
= xtable
, *yt
= ytable
;
871 register unsigned int x
, y
;
873 dry
= drx
= (float) (to
.red() - from
.red());
874 dgy
= dgx
= (float) (to
.green() - from
.green());
875 dby
= dbx
= (float) (to
.blue() - from
.blue());
882 for (x
= 0; x
< width
; x
++) {
883 *(xt
++) = (unsigned char) (xr
);
884 *(xt
++) = (unsigned char) (xg
);
885 *(xt
++) = (unsigned char) (xb
);
897 for (y
= 0; y
< height
; y
++) {
898 *(yt
++) = ((unsigned char) yr
);
899 *(yt
++) = ((unsigned char) yg
);
900 *(yt
++) = ((unsigned char) yb
);
907 // Combine tables to create gradient
911 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
912 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
913 *(pr
++) = *(xt
++) + *(yt
);
914 *(pg
++) = *(xt
++) + *(yt
+ 1);
915 *(pb
++) = *(xt
++) + *(yt
+ 2);
919 // faked interlacing effect
920 unsigned char channel
, channel2
;
922 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
923 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
925 channel
= *(xt
++) + *(yt
);
926 channel2
= (channel
>> 1) + (channel
>> 2);
927 if (channel2
> channel
) channel2
= 0;
930 channel
= *(xt
++) + *(yt
+ 1);
931 channel2
= (channel
>> 1) + (channel
>> 2);
932 if (channel2
> channel
) channel2
= 0;
935 channel
= *(xt
++) + *(yt
+ 2);
936 channel2
= (channel
>> 1) + (channel
>> 2);
937 if (channel2
> channel
) channel2
= 0;
940 channel
= *(xt
++) + *(yt
);
941 channel2
= channel
+ (channel
>> 3);
942 if (channel2
< channel
) channel2
= ~0;
945 channel
= *(xt
++) + *(yt
+ 1);
946 channel2
= channel
+ (channel
>> 3);
947 if (channel2
< channel
) channel2
= ~0;
950 channel
= *(xt
++) + *(yt
+ 2);
951 channel2
= channel
+ (channel
>> 3);
952 if (channel2
< channel
) channel2
= ~0;
961 void BImage::hgradient(void) {
963 xr
= (float) from
.red(),
964 xg
= (float) from
.green(),
965 xb
= (float) from
.blue();
966 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
968 register unsigned int x
, y
;
970 drx
= (float) (to
.red() - from
.red());
971 dgx
= (float) (to
.green() - from
.green());
972 dbx
= (float) (to
.blue() - from
.blue());
978 if (interlaced
&& height
> 2) {
979 // faked interlacing effect
980 unsigned char channel
, channel2
;
982 for (x
= 0; x
< width
; x
++, pr
++, pg
++, pb
++) {
983 channel
= (unsigned char) xr
;
984 channel2
= (channel
>> 1) + (channel
>> 2);
985 if (channel2
> channel
) channel2
= 0;
988 channel
= (unsigned char) xg
;
989 channel2
= (channel
>> 1) + (channel
>> 2);
990 if (channel2
> channel
) channel2
= 0;
993 channel
= (unsigned char) xb
;
994 channel2
= (channel
>> 1) + (channel
>> 2);
995 if (channel2
> channel
) channel2
= 0;
999 channel
= (unsigned char) xr
;
1000 channel2
= channel
+ (channel
>> 3);
1001 if (channel2
< channel
) channel2
= ~0;
1002 *(pr
+ width
) = channel2
;
1004 channel
= (unsigned char) xg
;
1005 channel2
= channel
+ (channel
>> 3);
1006 if (channel2
< channel
) channel2
= ~0;
1007 *(pg
+ width
) = channel2
;
1009 channel
= (unsigned char) xb
;
1010 channel2
= channel
+ (channel
>> 3);
1011 if (channel2
< channel
) channel2
= ~0;
1012 *(pb
+ width
) = channel2
;
1025 for (y
= 2; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1026 if (y
& 1) offset
= width
; else offset
= 0;
1028 memcpy(pr
, (red
+ offset
), width
);
1029 memcpy(pg
, (green
+ offset
), width
);
1030 memcpy(pb
, (blue
+ offset
), width
);
1034 for (x
= 0; x
< width
; x
++) {
1035 *(pr
++) = (unsigned char) (xr
);
1036 *(pg
++) = (unsigned char) (xg
);
1037 *(pb
++) = (unsigned char) (xb
);
1044 for (y
= 1; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1045 memcpy(pr
, red
, width
);
1046 memcpy(pg
, green
, width
);
1047 memcpy(pb
, blue
, width
);
1053 void BImage::vgradient(void) {
1054 float dry
, dgy
, dby
,
1055 yr
= (float) from
.red(),
1056 yg
= (float) from
.green(),
1057 yb
= (float) from
.blue();
1058 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1060 register unsigned int y
;
1062 dry
= (float) (to
.red() - from
.red());
1063 dgy
= (float) (to
.green() - from
.green());
1064 dby
= (float) (to
.blue() - from
.blue());
1071 // faked interlacing effect
1072 unsigned char channel
, channel2
;
1074 for (y
= 0; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1076 channel
= (unsigned char) yr
;
1077 channel2
= (channel
>> 1) + (channel
>> 2);
1078 if (channel2
> channel
) channel2
= 0;
1079 memset(pr
, channel2
, width
);
1081 channel
= (unsigned char) yg
;
1082 channel2
= (channel
>> 1) + (channel
>> 2);
1083 if (channel2
> channel
) channel2
= 0;
1084 memset(pg
, channel2
, width
);
1086 channel
= (unsigned char) yb
;
1087 channel2
= (channel
>> 1) + (channel
>> 2);
1088 if (channel2
> channel
) channel2
= 0;
1089 memset(pb
, channel2
, width
);
1091 channel
= (unsigned char) yr
;
1092 channel2
= channel
+ (channel
>> 3);
1093 if (channel2
< channel
) channel2
= ~0;
1094 memset(pr
, channel2
, width
);
1096 channel
= (unsigned char) yg
;
1097 channel2
= channel
+ (channel
>> 3);
1098 if (channel2
< channel
) channel2
= ~0;
1099 memset(pg
, channel2
, width
);
1101 channel
= (unsigned char) yb
;
1102 channel2
= channel
+ (channel
>> 3);
1103 if (channel2
< channel
) channel2
= ~0;
1104 memset(pb
, channel2
, width
);
1113 for (y
= 0; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1114 memset(pr
, (unsigned char) yr
, width
);
1115 memset(pg
, (unsigned char) yg
, width
);
1116 memset(pb
, (unsigned char) yb
, width
);
1126 void BImage::pgradient(void) {
1127 // pyramid gradient - based on original dgradient, written by
1128 // Mosfet (mosfet@kde.org)
1129 // adapted from kde sources for Blackbox by Brad Hughes
1131 float yr
, yg
, yb
, drx
, dgx
, dbx
, dry
, dgy
, dby
,
1133 int rsign
, gsign
, bsign
;
1134 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1135 unsigned int tr
= to
.red(), tg
= to
.green(), tb
= to
.blue(),
1136 *xt
= xtable
, *yt
= ytable
;
1138 register unsigned int x
, y
;
1140 dry
= drx
= (float) (to
.red() - from
.red());
1141 dgy
= dgx
= (float) (to
.green() - from
.green());
1142 dby
= dbx
= (float) (to
.blue() - from
.blue());
1144 rsign
= (drx
< 0) ? -1 : 1;
1145 gsign
= (dgx
< 0) ? -1 : 1;
1146 bsign
= (dbx
< 0) ? -1 : 1;
1148 xr
= yr
= (drx
/ 2);
1149 xg
= yg
= (dgx
/ 2);
1150 xb
= yb
= (dbx
/ 2);
1157 for (x
= 0; x
< width
; x
++) {
1158 *(xt
++) = (unsigned char) ((xr
< 0) ? -xr
: xr
);
1159 *(xt
++) = (unsigned char) ((xg
< 0) ? -xg
: xg
);
1160 *(xt
++) = (unsigned char) ((xb
< 0) ? -xb
: xb
);
1172 for (y
= 0; y
< height
; y
++) {
1173 *(yt
++) = ((unsigned char) ((yr
< 0) ? -yr
: yr
));
1174 *(yt
++) = ((unsigned char) ((yg
< 0) ? -yg
: yg
));
1175 *(yt
++) = ((unsigned char) ((yb
< 0) ? -yb
: yb
));
1182 // Combine tables to create gradient
1186 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1187 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1188 *(pr
++) = (unsigned char) (tr
- (rsign
* (*(xt
++) + *(yt
))));
1189 *(pg
++) = (unsigned char) (tg
- (gsign
* (*(xt
++) + *(yt
+ 1))));
1190 *(pb
++) = (unsigned char) (tb
- (bsign
* (*(xt
++) + *(yt
+ 2))));
1194 // faked interlacing effect
1195 unsigned char channel
, channel2
;
1197 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1198 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1200 channel
= (unsigned char) (tr
- (rsign
* (*(xt
++) + *(yt
))));
1201 channel2
= (channel
>> 1) + (channel
>> 2);
1202 if (channel2
> channel
) channel2
= 0;
1205 channel
= (unsigned char) (tg
- (gsign
* (*(xt
++) + *(yt
+ 1))));
1206 channel2
= (channel
>> 1) + (channel
>> 2);
1207 if (channel2
> channel
) channel2
= 0;
1210 channel
= (unsigned char) (tb
- (bsign
* (*(xt
++) + *(yt
+ 2))));
1211 channel2
= (channel
>> 1) + (channel
>> 2);
1212 if (channel2
> channel
) channel2
= 0;
1215 channel
= (unsigned char) (tr
- (rsign
* (*(xt
++) + *(yt
))));
1216 channel2
= channel
+ (channel
>> 3);
1217 if (channel2
< channel
) channel2
= ~0;
1220 channel
= (unsigned char) (tg
- (gsign
* (*(xt
++) + *(yt
+ 1))));
1221 channel2
= channel
+ (channel
>> 3);
1222 if (channel2
< channel
) channel2
= ~0;
1225 channel
= (unsigned char) (tb
- (bsign
* (*(xt
++) + *(yt
+ 2))));
1226 channel2
= channel
+ (channel
>> 3);
1227 if (channel2
< channel
) channel2
= ~0;
1236 void BImage::rgradient(void) {
1237 // rectangle gradient - based on original dgradient, written by
1238 // Mosfet (mosfet@kde.org)
1239 // adapted from kde sources for Blackbox by Brad Hughes
1241 float drx
, dgx
, dbx
, dry
, dgy
, dby
, xr
, xg
, xb
, yr
, yg
, yb
;
1242 int rsign
, gsign
, bsign
;
1243 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1244 unsigned int tr
= to
.red(), tg
= to
.green(), tb
= to
.blue(),
1245 *xt
= xtable
, *yt
= ytable
;
1247 register unsigned int x
, y
;
1249 dry
= drx
= (float) (to
.red() - from
.red());
1250 dgy
= dgx
= (float) (to
.green() - from
.green());
1251 dby
= dbx
= (float) (to
.blue() - from
.blue());
1253 rsign
= (drx
< 0) ? -2 : 2;
1254 gsign
= (dgx
< 0) ? -2 : 2;
1255 bsign
= (dbx
< 0) ? -2 : 2;
1257 xr
= yr
= (drx
/ 2);
1258 xg
= yg
= (dgx
/ 2);
1259 xb
= yb
= (dbx
/ 2);
1266 for (x
= 0; x
< width
; x
++) {
1267 *(xt
++) = (unsigned char) ((xr
< 0) ? -xr
: xr
);
1268 *(xt
++) = (unsigned char) ((xg
< 0) ? -xg
: xg
);
1269 *(xt
++) = (unsigned char) ((xb
< 0) ? -xb
: xb
);
1281 for (y
= 0; y
< height
; y
++) {
1282 *(yt
++) = ((unsigned char) ((yr
< 0) ? -yr
: yr
));
1283 *(yt
++) = ((unsigned char) ((yg
< 0) ? -yg
: yg
));
1284 *(yt
++) = ((unsigned char) ((yb
< 0) ? -yb
: yb
));
1291 // Combine tables to create gradient
1295 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1296 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1297 *(pr
++) = (unsigned char) (tr
- (rsign
* max(*(xt
++), *(yt
))));
1298 *(pg
++) = (unsigned char) (tg
- (gsign
* max(*(xt
++), *(yt
+ 1))));
1299 *(pb
++) = (unsigned char) (tb
- (bsign
* max(*(xt
++), *(yt
+ 2))));
1303 // faked interlacing effect
1304 unsigned char channel
, channel2
;
1306 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1307 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1309 channel
= (unsigned char) (tr
- (rsign
* max(*(xt
++), *(yt
))));
1310 channel2
= (channel
>> 1) + (channel
>> 2);
1311 if (channel2
> channel
) channel2
= 0;
1314 channel
= (unsigned char) (tg
- (gsign
* max(*(xt
++), *(yt
+ 1))));
1315 channel2
= (channel
>> 1) + (channel
>> 2);
1316 if (channel2
> channel
) channel2
= 0;
1319 channel
= (unsigned char) (tb
- (bsign
* max(*(xt
++), *(yt
+ 2))));
1320 channel2
= (channel
>> 1) + (channel
>> 2);
1321 if (channel2
> channel
) channel2
= 0;
1324 channel
= (unsigned char) (tr
- (rsign
* max(*(xt
++), *(yt
))));
1325 channel2
= channel
+ (channel
>> 3);
1326 if (channel2
< channel
) channel2
= ~0;
1329 channel
= (unsigned char) (tg
- (gsign
* max(*(xt
++), *(yt
+ 1))));
1330 channel2
= channel
+ (channel
>> 3);
1331 if (channel2
< channel
) channel2
= ~0;
1334 channel
= (unsigned char) (tb
- (bsign
* max(*(xt
++), *(yt
+ 2))));
1335 channel2
= channel
+ (channel
>> 3);
1336 if (channel2
< channel
) channel2
= ~0;
1345 void BImage::egradient(void) {
1346 // elliptic gradient - based on original dgradient, written by
1347 // Mosfet (mosfet@kde.org)
1348 // adapted from kde sources for Blackbox by Brad Hughes
1350 float drx
, dgx
, dbx
, dry
, dgy
, dby
, yr
, yg
, yb
, xr
, xg
, xb
;
1351 int rsign
, gsign
, bsign
;
1352 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1353 unsigned int *xt
= xtable
, *yt
= ytable
,
1354 tr
= (unsigned long) to
.red(),
1355 tg
= (unsigned long) to
.green(),
1356 tb
= (unsigned long) to
.blue();
1358 register unsigned int x
, y
;
1360 dry
= drx
= (float) (to
.red() - from
.red());
1361 dgy
= dgx
= (float) (to
.green() - from
.green());
1362 dby
= dbx
= (float) (to
.blue() - from
.blue());
1364 rsign
= (drx
< 0) ? -1 : 1;
1365 gsign
= (dgx
< 0) ? -1 : 1;
1366 bsign
= (dbx
< 0) ? -1 : 1;
1368 xr
= yr
= (drx
/ 2);
1369 xg
= yg
= (dgx
/ 2);
1370 xb
= yb
= (dbx
/ 2);
1377 for (x
= 0; x
< width
; x
++) {
1378 *(xt
++) = (unsigned long) (xr
* xr
);
1379 *(xt
++) = (unsigned long) (xg
* xg
);
1380 *(xt
++) = (unsigned long) (xb
* xb
);
1392 for (y
= 0; y
< height
; y
++) {
1393 *(yt
++) = (unsigned long) (yr
* yr
);
1394 *(yt
++) = (unsigned long) (yg
* yg
);
1395 *(yt
++) = (unsigned long) (yb
* yb
);
1402 // Combine tables to create gradient
1406 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1407 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1408 *(pr
++) = (unsigned char)
1409 (tr
- (rsign
* control
->getSqrt(*(xt
++) + *(yt
))));
1410 *(pg
++) = (unsigned char)
1411 (tg
- (gsign
* control
->getSqrt(*(xt
++) + *(yt
+ 1))));
1412 *(pb
++) = (unsigned char)
1413 (tb
- (bsign
* control
->getSqrt(*(xt
++) + *(yt
+ 2))));
1417 // faked interlacing effect
1418 unsigned char channel
, channel2
;
1420 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1421 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1423 channel
= (unsigned char)
1424 (tr
- (rsign
* control
->getSqrt(*(xt
++) + *(yt
))));
1425 channel2
= (channel
>> 1) + (channel
>> 2);
1426 if (channel2
> channel
) channel2
= 0;
1429 channel
= (unsigned char)
1430 (tg
- (gsign
* control
->getSqrt(*(xt
++) + *(yt
+ 1))));
1431 channel2
= (channel
>> 1) + (channel
>> 2);
1432 if (channel2
> channel
) channel2
= 0;
1435 channel
= (unsigned char)
1436 (tb
- (bsign
* control
->getSqrt(*(xt
++) + *(yt
+ 2))));
1437 channel2
= (channel
>> 1) + (channel
>> 2);
1438 if (channel2
> channel
) channel2
= 0;
1441 channel
= (unsigned char)
1442 (tr
- (rsign
* control
->getSqrt(*(xt
++) + *(yt
))));
1443 channel2
= channel
+ (channel
>> 3);
1444 if (channel2
< channel
) channel2
= ~0;
1447 channel
= (unsigned char)
1448 (tg
- (gsign
* control
->getSqrt(*(xt
++) + *(yt
+ 1))));
1449 channel2
= channel
+ (channel
>> 3);
1450 if (channel2
< channel
) channel2
= ~0;
1453 channel
= (unsigned char)
1454 (tb
- (bsign
* control
->getSqrt(*(xt
++) + *(yt
+ 2))));
1455 channel2
= channel
+ (channel
>> 3);
1456 if (channel2
< channel
) channel2
= ~0;
1465 void BImage::pcgradient(void) {
1466 // pipe cross gradient - based on original dgradient, written by
1467 // Mosfet (mosfet@kde.org)
1468 // adapted from kde sources for Blackbox by Brad Hughes
1470 float drx
, dgx
, dbx
, dry
, dgy
, dby
, xr
, xg
, xb
, yr
, yg
, yb
;
1471 int rsign
, gsign
, bsign
;
1472 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1473 unsigned int *xt
= xtable
, *yt
= ytable
,
1478 register unsigned int x
, y
;
1480 dry
= drx
= (float) (to
.red() - from
.red());
1481 dgy
= dgx
= (float) (to
.green() - from
.green());
1482 dby
= dbx
= (float) (to
.blue() - from
.blue());
1484 rsign
= (drx
< 0) ? -2 : 2;
1485 gsign
= (dgx
< 0) ? -2 : 2;
1486 bsign
= (dbx
< 0) ? -2 : 2;
1488 xr
= yr
= (drx
/ 2);
1489 xg
= yg
= (dgx
/ 2);
1490 xb
= yb
= (dbx
/ 2);
1497 for (x
= 0; x
< width
; x
++) {
1498 *(xt
++) = (unsigned char) ((xr
< 0) ? -xr
: xr
);
1499 *(xt
++) = (unsigned char) ((xg
< 0) ? -xg
: xg
);
1500 *(xt
++) = (unsigned char) ((xb
< 0) ? -xb
: xb
);
1512 for (y
= 0; y
< height
; y
++) {
1513 *(yt
++) = ((unsigned char) ((yr
< 0) ? -yr
: yr
));
1514 *(yt
++) = ((unsigned char) ((yg
< 0) ? -yg
: yg
));
1515 *(yt
++) = ((unsigned char) ((yb
< 0) ? -yb
: yb
));
1522 // Combine tables to create gradient
1525 // normal pcgradient
1526 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1527 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1528 *(pr
++) = (unsigned char) (tr
- (rsign
* min(*(xt
++), *(yt
))));
1529 *(pg
++) = (unsigned char) (tg
- (gsign
* min(*(xt
++), *(yt
+ 1))));
1530 *(pb
++) = (unsigned char) (tb
- (bsign
* min(*(xt
++), *(yt
+ 2))));
1534 // faked interlacing effect
1535 unsigned char channel
, channel2
;
1537 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1538 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1540 channel
= (unsigned char) (tr
- (rsign
* min(*(xt
++), *(yt
))));
1541 channel2
= (channel
>> 1) + (channel
>> 2);
1542 if (channel2
> channel
) channel2
= 0;
1545 channel
= (unsigned char) (tg
- (bsign
* min(*(xt
++), *(yt
+ 1))));
1546 channel2
= (channel
>> 1) + (channel
>> 2);
1547 if (channel2
> channel
) channel2
= 0;
1550 channel
= (unsigned char) (tb
- (gsign
* min(*(xt
++), *(yt
+ 2))));
1551 channel2
= (channel
>> 1) + (channel
>> 2);
1552 if (channel2
> channel
) channel2
= 0;
1555 channel
= (unsigned char) (tr
- (rsign
* min(*(xt
++), *(yt
))));
1556 channel2
= channel
+ (channel
>> 3);
1557 if (channel2
< channel
) channel2
= ~0;
1560 channel
= (unsigned char) (tg
- (gsign
* min(*(xt
++), *(yt
+ 1))));
1561 channel2
= channel
+ (channel
>> 3);
1562 if (channel2
< channel
) channel2
= ~0;
1565 channel
= (unsigned char) (tb
- (bsign
* min(*(xt
++), *(yt
+ 2))));
1566 channel2
= channel
+ (channel
>> 3);
1567 if (channel2
< channel
) channel2
= ~0;
1576 void BImage::cdgradient(void) {
1577 // cross diagonal gradient - based on original dgradient, written by
1578 // Mosfet (mosfet@kde.org)
1579 // adapted from kde sources for Blackbox by Brad Hughes
1581 float drx
, dgx
, dbx
, dry
, dgy
, dby
, yr
= 0.0, yg
= 0.0, yb
= 0.0,
1582 xr
= (float) from
.red(),
1583 xg
= (float) from
.green(),
1584 xb
= (float) from
.blue();
1585 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1586 unsigned int w
= width
* 2, h
= height
* 2, *xt
, *yt
;
1588 register unsigned int x
, y
;
1590 dry
= drx
= (float) (to
.red() - from
.red());
1591 dgy
= dgx
= (float) (to
.green() - from
.green());
1592 dby
= dbx
= (float) (to
.blue() - from
.blue());
1599 for (xt
= (xtable
+ (width
* 3) - 1), x
= 0; x
< width
; x
++) {
1600 *(xt
--) = (unsigned char) xb
;
1601 *(xt
--) = (unsigned char) xg
;
1602 *(xt
--) = (unsigned char) xr
;
1614 for (yt
= ytable
, y
= 0; y
< height
; y
++) {
1615 *(yt
++) = (unsigned char) yr
;
1616 *(yt
++) = (unsigned char) yg
;
1617 *(yt
++) = (unsigned char) yb
;
1624 // Combine tables to create gradient
1627 // normal cdgradient
1628 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1629 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1630 *(pr
++) = *(xt
++) + *(yt
);
1631 *(pg
++) = *(xt
++) + *(yt
+ 1);
1632 *(pb
++) = *(xt
++) + *(yt
+ 2);
1636 // faked interlacing effect
1637 unsigned char channel
, channel2
;
1639 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1640 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1642 channel
= *(xt
++) + *(yt
);
1643 channel2
= (channel
>> 1) + (channel
>> 2);
1644 if (channel2
> channel
) channel2
= 0;
1647 channel
= *(xt
++) + *(yt
+ 1);
1648 channel2
= (channel
>> 1) + (channel
>> 2);
1649 if (channel2
> channel
) channel2
= 0;
1652 channel
= *(xt
++) + *(yt
+ 2);
1653 channel2
= (channel
>> 1) + (channel
>> 2);
1654 if (channel2
> channel
) channel2
= 0;
1657 channel
= *(xt
++) + *(yt
);
1658 channel2
= channel
+ (channel
>> 3);
1659 if (channel2
< channel
) channel2
= ~0;
1662 channel
= *(xt
++) + *(yt
+ 1);
1663 channel2
= channel
+ (channel
>> 3);
1664 if (channel2
< channel
) channel2
= ~0;
1667 channel
= *(xt
++) + *(yt
+ 2);
1668 channel2
= channel
+ (channel
>> 3);
1669 if (channel2
< channel
) channel2
= ~0;
This page took 0.119251 seconds and 4 git commands to generate.