]>
Dogcows Code - chaz/openbox/blob - otk/image.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
4 # include "../config.h"
5 #endif // HAVE_CONFIG_H
22 Image::Image(ImageControl
*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
);
53 Pixmap
Image::render(const Texture
&texture
) {
54 if (texture
.texture() & Texture::Parent_Relative
)
55 return ParentRelative
;
56 else if (texture
.texture() & Texture::Solid
)
57 return render_solid(texture
);
58 else if (texture
.texture() & Texture::Gradient
)
59 return render_gradient(texture
);
64 Pixmap
Image::render_solid(const Texture
&texture
) {
65 Pixmap pixmap
= XCreatePixmap(**display
, control
->getDrawable(), width
,
66 height
, control
->getDepth());
68 fprintf(stderr
, "Image::render_solid: error creating pixmap\n");
72 Pen
pen(texture
.color());
73 Pen
penlight(texture
.lightColor());
74 Pen
penshadow(texture
.shadowColor());
76 XFillRectangle(**display
, pixmap
, pen
.gc(), 0, 0, width
, height
);
78 if (texture
.texture() & Texture::Interlaced
) {
79 Pen
peninterlace(texture
.colorTo());
80 for (unsigned int i
= 0; i
< height
; i
+= 2)
81 XDrawLine(**display
, pixmap
, peninterlace
.gc(), 0, i
, width
, i
);
84 int left
= 0, top
= 0, right
= width
- 1, bottom
= height
- 1;
86 if (texture
.texture() & Texture::Border
) {
87 Pen
penborder(texture
.borderColor());
88 XDrawRectangle(**display
, pixmap
, penborder
.gc(),
89 left
, top
, right
, bottom
);
92 if (texture
.texture() & Texture::Bevel1
) {
93 if (texture
.texture() & Texture::Raised
) {
94 XDrawLine(**display
, pixmap
, penshadow
.gc(),
95 left
, bottom
, right
, bottom
);
96 XDrawLine(**display
, pixmap
, penshadow
.gc(),
97 right
, bottom
, right
, top
);
99 XDrawLine(**display
, pixmap
, penlight
.gc(),
100 left
, top
, right
, top
);
101 XDrawLine(**display
, pixmap
, penlight
.gc(),
102 left
, bottom
, left
, top
);
103 } else if (texture
.texture() & Texture::Sunken
) {
104 XDrawLine(**display
, pixmap
, penlight
.gc(),
105 left
, bottom
, right
, bottom
);
106 XDrawLine(**display
, pixmap
, penlight
.gc(),
107 right
, bottom
, right
, top
);
109 XDrawLine(**display
, pixmap
, penshadow
.gc(),
110 left
, top
, right
, top
);
111 XDrawLine(**display
, pixmap
, penshadow
.gc(),
112 left
, bottom
, left
, top
);
114 } else if (texture
.texture() & Texture::Bevel2
) {
115 if (texture
.texture() & Texture::Raised
) {
116 XDrawLine(**display
, pixmap
, penshadow
.gc(),
117 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
118 XDrawLine(**display
, pixmap
, penshadow
.gc(),
119 right
- 2, bottom
- 2, right
- 2, top
+ 1);
121 XDrawLine(**display
, pixmap
, penlight
.gc(),
122 left
+ 1, top
+ 1, right
- 2, top
+ 1);
123 XDrawLine(**display
, pixmap
, penlight
.gc(),
124 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
125 } else if (texture
.texture() & Texture::Sunken
) {
126 XDrawLine(**display
, pixmap
, penlight
.gc(),
127 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
128 XDrawLine(**display
, pixmap
, penlight
.gc(),
129 right
- 2, bottom
- 2, right
- 2, top
+ 1);
131 XDrawLine(**display
, pixmap
, penshadow
.gc(),
132 left
+ 1, top
+ 1, right
- 2, top
+ 1);
133 XDrawLine(**display
, pixmap
, penshadow
.gc(),
134 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
142 Pixmap
Image::render_gradient(const Texture
&texture
) {
143 bool inverted
= False
;
145 interlaced
= texture
.texture() & Texture::Interlaced
;
147 if (texture
.texture() & Texture::Sunken
) {
148 from
= texture
.colorTo();
149 to
= texture
.color();
151 if (! (texture
.texture() & Texture::Invert
)) inverted
= True
;
153 from
= texture
.color();
154 to
= texture
.colorTo();
156 if (texture
.texture() & Texture::Invert
) inverted
= True
;
159 control
->getGradientBuffers(width
, height
, &xtable
, &ytable
);
161 if (texture
.texture() & Texture::Diagonal
) dgradient();
162 else if (texture
.texture() & Texture::Elliptic
) egradient();
163 else if (texture
.texture() & Texture::Horizontal
) hgradient();
164 else if (texture
.texture() & Texture::Pyramid
) pgradient();
165 else if (texture
.texture() & Texture::Rectangle
) rgradient();
166 else if (texture
.texture() & Texture::Vertical
) vgradient();
167 else if (texture
.texture() & Texture::CrossDiagonal
) cdgradient();
168 else if (texture
.texture() & Texture::PipeCross
) pcgradient();
170 if (texture
.texture() & Texture::Bevel1
) bevel1();
171 else if (texture
.texture() & Texture::Bevel2
) bevel2();
173 if (texture
.texture() & Texture::Border
) border(texture
);
175 if (inverted
) invert();
177 return renderPixmap();
182 static const unsigned char dither4
[4][4] = {
191 * Helper function for TrueColorDither and renderXImage
193 * This handles the proper setting of the image data based on the image depth
194 * and the machine's byte ordering
197 void assignPixelData(unsigned int bit_depth
, unsigned char **data
,
198 unsigned long pixel
) {
199 unsigned char *pixel_data
= *data
;
202 *pixel_data
++ = pixel
;
205 case 16: // 16bpp LSB
206 *pixel_data
++ = pixel
;
207 *pixel_data
++ = pixel
>> 8;
210 case 17: // 16bpp MSB
211 *pixel_data
++ = pixel
>> 8;
212 *pixel_data
++ = pixel
;
215 case 24: // 24bpp LSB
216 *pixel_data
++ = pixel
;
217 *pixel_data
++ = pixel
>> 8;
218 *pixel_data
++ = pixel
>> 16;
221 case 25: // 24bpp MSB
222 *pixel_data
++ = pixel
>> 16;
223 *pixel_data
++ = pixel
>> 8;
224 *pixel_data
++ = pixel
;
227 case 32: // 32bpp LSB
228 *pixel_data
++ = pixel
;
229 *pixel_data
++ = pixel
>> 8;
230 *pixel_data
++ = pixel
>> 16;
231 *pixel_data
++ = pixel
>> 24;
234 case 33: // 32bpp MSB
235 *pixel_data
++ = pixel
>> 24;
236 *pixel_data
++ = pixel
>> 16;
237 *pixel_data
++ = pixel
>> 8;
238 *pixel_data
++ = pixel
;
241 *data
= pixel_data
; // assign back so we don't lose our place
245 // algorithm: ordered dithering... many many thanks to rasterman
246 // (raster@rasterman.com) for telling me about this... portions of this
247 // code is based off of his code in Imlib
248 void Image::TrueColorDither(unsigned int bit_depth
, int bytes_per_line
,
249 unsigned char *pixel_data
) {
250 unsigned int x
, y
, dithx
, dithy
, r
, g
, b
, er
, eg
, eb
, offset
;
251 unsigned char *ppixel_data
= pixel_data
;
254 for (y
= 0, offset
= 0; y
< height
; y
++) {
257 for (x
= 0; x
< width
; x
++, offset
++) {
263 er
= r
& (red_bits
- 1);
264 eg
= g
& (green_bits
- 1);
265 eb
= b
& (blue_bits
- 1);
271 if ((dither4
[dithy
][dithx
] < er
) && (r
< red_table
[255])) r
++;
272 if ((dither4
[dithy
][dithx
] < eg
) && (g
< green_table
[255])) g
++;
273 if ((dither4
[dithy
][dithx
] < eb
) && (b
< blue_table
[255])) b
++;
275 pixel
= (r
<< red_offset
) | (g
<< green_offset
) | (b
<< blue_offset
);
276 assignPixelData(bit_depth
, &pixel_data
, pixel
);
279 pixel_data
= (ppixel_data
+= bytes_per_line
);
284 const static unsigned char dither8
[8][8] = {
285 { 0, 32, 8, 40, 2, 34, 10, 42},
286 { 48, 16, 56, 24, 50, 18, 58, 26},
287 { 12, 44, 4, 36, 14, 46, 6, 38},
288 { 60, 28, 52, 20, 62, 30, 54, 22},
289 { 3, 35, 11, 43, 1, 33, 9, 41},
290 { 51, 19, 59, 27, 49, 17, 57, 25},
291 { 15, 47, 7, 39, 13, 45, 5, 37},
292 { 63, 31, 55, 23, 61, 29, 53, 21}
295 void Image::OrderedPseudoColorDither(int bytes_per_line
,
296 unsigned char *pixel_data
) {
297 unsigned int x
, y
, dithx
, dithy
, r
, g
, b
, er
, eg
, eb
, offset
;
299 unsigned char *ppixel_data
= pixel_data
;
301 for (y
= 0, offset
= 0; y
< height
; y
++) {
304 for (x
= 0; x
< width
; x
++, offset
++) {
311 er
= r
& (red_bits
- 1);
312 eg
= g
& (green_bits
- 1);
313 eb
= b
& (blue_bits
- 1);
319 if ((dither8
[dithy
][dithx
] < er
) && (r
< red_table
[255])) r
++;
320 if ((dither8
[dithy
][dithx
] < eg
) && (g
< green_table
[255])) g
++;
321 if ((dither8
[dithy
][dithx
] < eb
) && (b
< blue_table
[255])) b
++;
323 pixel
= (r
* cpccpc
) + (g
* cpc
) + b
;
324 *(pixel_data
++) = colors
[pixel
].pixel
;
327 pixel_data
= (ppixel_data
+= bytes_per_line
);
332 void Image::PseudoColorDither(int bytes_per_line
, unsigned char *pixel_data
) {
334 *rerr
= new short[width
+ 2],
335 *gerr
= new short[width
+ 2],
336 *berr
= new short[width
+ 2],
337 *nrerr
= new short[width
+ 2],
338 *ngerr
= new short[width
+ 2],
339 *nberr
= new short[width
+ 2];
341 int rr
, gg
, bb
, rer
, ger
, ber
;
342 int dd
= 255 / control
->getColorsPerChannel();
343 unsigned int x
, y
, r
, g
, b
, offset
;
345 unsigned char *ppixel_data
= pixel_data
;
347 for (x
= 0; x
< width
; x
++) {
348 *(rerr
+ x
) = *(red
+ x
);
349 *(gerr
+ x
) = *(green
+ x
);
350 *(berr
+ x
) = *(blue
+ x
);
353 *(rerr
+ x
) = *(gerr
+ x
) = *(berr
+ x
) = 0;
355 for (y
= 0, offset
= 0; y
< height
; y
++) {
356 if (y
< (height
- 1)) {
357 int i
= offset
+ width
;
358 for (x
= 0; x
< width
; x
++, i
++) {
359 *(nrerr
+ x
) = *(red
+ i
);
360 *(ngerr
+ x
) = *(green
+ i
);
361 *(nberr
+ x
) = *(blue
+ i
);
364 *(nrerr
+ x
) = *(red
+ (--i
));
365 *(ngerr
+ x
) = *(green
+ i
);
366 *(nberr
+ x
) = *(blue
+ i
);
369 for (x
= 0; x
< width
; x
++) {
374 if (rr
> 255) rr
= 255; else if (rr
< 0) rr
= 0;
375 if (gg
> 255) gg
= 255; else if (gg
< 0) gg
= 0;
376 if (bb
> 255) bb
= 255; else if (bb
< 0) bb
= 0;
382 rer
= rerr
[x
] - r
*dd
;
383 ger
= gerr
[x
] - g
*dd
;
384 ber
= berr
[x
] - b
*dd
;
386 pixel
= (r
* cpccpc
) + (g
* cpc
) + b
;
387 *pixel_data
++ = colors
[pixel
].pixel
;
402 pixel_data
= (ppixel_data
+= bytes_per_line
);
425 XImage
*Image::renderXImage(void) {
427 XCreateImage(**display
, control
->getVisual(), control
->getDepth(),
428 ZPixmap
, 0, 0,width
, height
, 32, 0);
431 fprintf(stderr
, "Image::renderXImage: error creating XImage\n");
436 image
->data
= (char *) 0;
438 unsigned char *d
= new unsigned char[image
->bytes_per_line
* (height
+ 1)];
440 unsigned int o
= image
->bits_per_pixel
+
441 ((image
->byte_order
== MSBFirst
) ? 1 : 0);
443 bool unsupported
= False
;
445 if (control
->doDither() && width
> 1 && height
> 1) {
446 switch (control
->getVisual()->c_class
) {
448 TrueColorDither(o
, image
->bytes_per_line
, d
);
454 OrderedPseudoColorDither(image
->bytes_per_line
, d
);
456 PseudoColorDither(image
->bytes_per_line
, d
);
465 unsigned int x
, y
, r
, g
, b
, offset
;
466 unsigned char *pixel_data
= d
, *ppixel_data
= d
;
469 switch (control
->getVisual()->c_class
) {
472 for (y
= 0, offset
= 0; y
< height
; ++y
) {
473 for (x
= 0; x
< width
; ++x
, ++offset
) {
474 r
= red_table
[red
[offset
]];
475 g
= green_table
[green
[offset
]];
476 b
= blue_table
[blue
[offset
]];
478 pixel
= (r
* cpccpc
) + (g
* cpc
) + b
;
479 *pixel_data
++ = colors
[pixel
].pixel
;
482 pixel_data
= (ppixel_data
+= image
->bytes_per_line
);
488 for (y
= 0, offset
= 0; y
< height
; y
++) {
489 for (x
= 0; x
< width
; x
++, offset
++) {
490 r
= red_table
[red
[offset
]];
491 g
= green_table
[green
[offset
]];
492 b
= blue_table
[blue
[offset
]];
494 pixel
= (r
<< red_offset
) | (g
<< green_offset
) | (b
<< blue_offset
);
495 assignPixelData(o
, &pixel_data
, pixel
);
498 pixel_data
= (ppixel_data
+= image
->bytes_per_line
);
505 for (y
= 0, offset
= 0; y
< height
; y
++) {
506 for (x
= 0; x
< width
; x
++, offset
++) {
507 r
= *(red_table
+ *(red
+ offset
));
508 g
= *(green_table
+ *(green
+ offset
));
509 b
= *(blue_table
+ *(blue
+ offset
));
511 g
= ((r
* 30) + (g
* 59) + (b
* 11)) / 100;
512 *pixel_data
++ = colors
[g
].pixel
;
515 pixel_data
= (ppixel_data
+= image
->bytes_per_line
);
526 fprintf(stderr
, "Image::renderXImage: unsupported visual\n");
528 XDestroyImage(image
);
532 image
->data
= (char *) d
;
538 Pixmap
Image::renderPixmap(void) {
540 XCreatePixmap(**display
, control
->getDrawable(), width
, height
,
541 control
->getDepth());
543 if (pixmap
== None
) {
544 fprintf(stderr
, "Image::renderPixmap: error creating pixmap\n");
548 XImage
*image
= renderXImage();
551 XFreePixmap(**display
, pixmap
);
556 XDestroyImage(image
);
557 XFreePixmap(**display
, pixmap
);
561 XPutImage(**display
, pixmap
,
562 DefaultGC(**display
, control
->getScreenInfo()->screen()),
563 image
, 0, 0, 0, 0, width
, height
);
566 delete [] image
->data
;
570 XDestroyImage(image
);
576 void Image::bevel1(void) {
577 if (width
> 2 && height
> 2) {
578 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
580 register unsigned char r
, g
, b
, rr
,gg
,bb
;
581 register unsigned int w
= width
, h
= height
- 1, wh
= w
* h
;
599 rr
= (r
>> 2) + (r
>> 1);
602 gg
= (g
>> 2) + (g
>> 1);
605 bb
= (b
>> 2) + (b
>> 1);
628 rr
= (r
>> 2) + (r
>> 1);
631 gg
= (g
>> 2) + (g
>> 1);
634 bb
= (b
>> 2) + (b
>> 1);
665 rr
= (r
>> 2) + (r
>> 1);
668 gg
= (g
>> 2) + (g
>> 1);
671 bb
= (b
>> 2) + (b
>> 1);
698 rr
= (r
>> 2) + (r
>> 1);
701 gg
= (g
>> 2) + (g
>> 1);
704 bb
= (b
>> 2) + (b
>> 1);
714 void Image::bevel2(void) {
715 if (width
> 4 && height
> 4) {
716 unsigned char r
, g
, b
, rr
,gg
,bb
, *pr
= red
+ width
+ 1,
717 *pg
= green
+ width
+ 1, *pb
= blue
+ width
+ 1;
718 unsigned int w
= width
- 2, h
= height
- 1, wh
= width
* (height
- 3);
736 rr
= (r
>> 2) + (r
>> 1);
739 gg
= (g
>> 2) + (g
>> 1);
742 bb
= (b
>> 2) + (b
>> 1);
774 rr
= (r
>> 2) + (r
>> 1);
777 gg
= (g
>> 2) + (g
>> 1);
780 bb
= (b
>> 2) + (b
>> 1);
793 void Image::border(const Texture
&texture
) {
794 if (width
< 2 || height
< 2) return;
796 register unsigned int i
;
797 int r
= texture
.borderColor().red(),
798 g
= texture
.borderColor().green(),
799 b
= texture
.borderColor().blue();
801 unsigned char *pr
, *pg
, *pb
;
807 for (i
= 0; i
< width
; ++i
) {
814 // left and right lines (pr,pg,pb are already lined up)
815 for (i
= 1; i
< height
- 1; ++i
) {
828 // bottom line (pr,pg,pb are already lined up)
829 for (i
= 0; i
< width
; ++i
) {
837 void Image::invert(void) {
838 register unsigned int i
, j
, wh
= (width
* height
) - 1;
841 for (i
= 0, j
= wh
; j
> i
; j
--, i
++) {
843 *(red
+ j
) = *(red
+ i
);
847 *(green
+ j
) = *(green
+ i
);
851 *(blue
+ j
) = *(blue
+ i
);
857 void Image::dgradient(void) {
858 // diagonal gradient code was written by Mike Cole <mike@mydot.com>
859 // modified for interlacing by Brad Hughes
861 float drx
, dgx
, dbx
, dry
, dgy
, dby
, yr
= 0.0, yg
= 0.0, yb
= 0.0,
862 xr
= (float) from
.red(),
863 xg
= (float) from
.green(),
864 xb
= (float) from
.blue();
865 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
866 unsigned int w
= width
* 2, h
= height
* 2, *xt
= xtable
, *yt
= ytable
;
868 register unsigned int x
, y
;
870 dry
= drx
= (float) (to
.red() - from
.red());
871 dgy
= dgx
= (float) (to
.green() - from
.green());
872 dby
= dbx
= (float) (to
.blue() - from
.blue());
879 for (x
= 0; x
< width
; x
++) {
880 *(xt
++) = (unsigned char) (xr
);
881 *(xt
++) = (unsigned char) (xg
);
882 *(xt
++) = (unsigned char) (xb
);
894 for (y
= 0; y
< height
; y
++) {
895 *(yt
++) = ((unsigned char) yr
);
896 *(yt
++) = ((unsigned char) yg
);
897 *(yt
++) = ((unsigned char) yb
);
904 // Combine tables to create gradient
908 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
909 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
910 *(pr
++) = *(xt
++) + *(yt
);
911 *(pg
++) = *(xt
++) + *(yt
+ 1);
912 *(pb
++) = *(xt
++) + *(yt
+ 2);
916 // faked interlacing effect
917 unsigned char channel
, channel2
;
919 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
920 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
922 channel
= *(xt
++) + *(yt
);
923 channel2
= (channel
>> 1) + (channel
>> 2);
924 if (channel2
> channel
) channel2
= 0;
927 channel
= *(xt
++) + *(yt
+ 1);
928 channel2
= (channel
>> 1) + (channel
>> 2);
929 if (channel2
> channel
) channel2
= 0;
932 channel
= *(xt
++) + *(yt
+ 2);
933 channel2
= (channel
>> 1) + (channel
>> 2);
934 if (channel2
> channel
) channel2
= 0;
937 channel
= *(xt
++) + *(yt
);
938 channel2
= channel
+ (channel
>> 3);
939 if (channel2
< channel
) channel2
= ~0;
942 channel
= *(xt
++) + *(yt
+ 1);
943 channel2
= channel
+ (channel
>> 3);
944 if (channel2
< channel
) channel2
= ~0;
947 channel
= *(xt
++) + *(yt
+ 2);
948 channel2
= channel
+ (channel
>> 3);
949 if (channel2
< channel
) channel2
= ~0;
958 void Image::hgradient(void) {
960 xr
= (float) from
.red(),
961 xg
= (float) from
.green(),
962 xb
= (float) from
.blue();
963 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
965 register unsigned int x
, y
;
967 drx
= (float) (to
.red() - from
.red());
968 dgx
= (float) (to
.green() - from
.green());
969 dbx
= (float) (to
.blue() - from
.blue());
975 if (interlaced
&& height
> 2) {
976 // faked interlacing effect
977 unsigned char channel
, channel2
;
979 for (x
= 0; x
< width
; x
++, pr
++, pg
++, pb
++) {
980 channel
= (unsigned char) xr
;
981 channel2
= (channel
>> 1) + (channel
>> 2);
982 if (channel2
> channel
) channel2
= 0;
985 channel
= (unsigned char) xg
;
986 channel2
= (channel
>> 1) + (channel
>> 2);
987 if (channel2
> channel
) channel2
= 0;
990 channel
= (unsigned char) xb
;
991 channel2
= (channel
>> 1) + (channel
>> 2);
992 if (channel2
> channel
) channel2
= 0;
996 channel
= (unsigned char) xr
;
997 channel2
= channel
+ (channel
>> 3);
998 if (channel2
< channel
) channel2
= ~0;
999 *(pr
+ width
) = channel2
;
1001 channel
= (unsigned char) xg
;
1002 channel2
= channel
+ (channel
>> 3);
1003 if (channel2
< channel
) channel2
= ~0;
1004 *(pg
+ width
) = channel2
;
1006 channel
= (unsigned char) xb
;
1007 channel2
= channel
+ (channel
>> 3);
1008 if (channel2
< channel
) channel2
= ~0;
1009 *(pb
+ width
) = channel2
;
1022 for (y
= 2; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1023 if (y
& 1) offset
= width
; else offset
= 0;
1025 memcpy(pr
, (red
+ offset
), width
);
1026 memcpy(pg
, (green
+ offset
), width
);
1027 memcpy(pb
, (blue
+ offset
), width
);
1031 for (x
= 0; x
< width
; x
++) {
1032 *(pr
++) = (unsigned char) (xr
);
1033 *(pg
++) = (unsigned char) (xg
);
1034 *(pb
++) = (unsigned char) (xb
);
1041 for (y
= 1; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1042 memcpy(pr
, red
, width
);
1043 memcpy(pg
, green
, width
);
1044 memcpy(pb
, blue
, width
);
1050 void Image::vgradient(void) {
1051 float dry
, dgy
, dby
,
1052 yr
= (float) from
.red(),
1053 yg
= (float) from
.green(),
1054 yb
= (float) from
.blue();
1055 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1057 register unsigned int y
;
1059 dry
= (float) (to
.red() - from
.red());
1060 dgy
= (float) (to
.green() - from
.green());
1061 dby
= (float) (to
.blue() - from
.blue());
1068 // faked interlacing effect
1069 unsigned char channel
, channel2
;
1071 for (y
= 0; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1073 channel
= (unsigned char) yr
;
1074 channel2
= (channel
>> 1) + (channel
>> 2);
1075 if (channel2
> channel
) channel2
= 0;
1076 memset(pr
, channel2
, width
);
1078 channel
= (unsigned char) yg
;
1079 channel2
= (channel
>> 1) + (channel
>> 2);
1080 if (channel2
> channel
) channel2
= 0;
1081 memset(pg
, channel2
, width
);
1083 channel
= (unsigned char) yb
;
1084 channel2
= (channel
>> 1) + (channel
>> 2);
1085 if (channel2
> channel
) channel2
= 0;
1086 memset(pb
, channel2
, width
);
1088 channel
= (unsigned char) yr
;
1089 channel2
= channel
+ (channel
>> 3);
1090 if (channel2
< channel
) channel2
= ~0;
1091 memset(pr
, channel2
, width
);
1093 channel
= (unsigned char) yg
;
1094 channel2
= channel
+ (channel
>> 3);
1095 if (channel2
< channel
) channel2
= ~0;
1096 memset(pg
, channel2
, width
);
1098 channel
= (unsigned char) yb
;
1099 channel2
= channel
+ (channel
>> 3);
1100 if (channel2
< channel
) channel2
= ~0;
1101 memset(pb
, channel2
, width
);
1110 for (y
= 0; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1111 memset(pr
, (unsigned char) yr
, width
);
1112 memset(pg
, (unsigned char) yg
, width
);
1113 memset(pb
, (unsigned char) yb
, width
);
1123 void Image::pgradient(void) {
1124 // pyramid gradient - based on original dgradient, written by
1125 // Mosfet (mosfet@kde.org)
1126 // adapted from kde sources for Blackbox by Brad Hughes
1128 float yr
, yg
, yb
, drx
, dgx
, dbx
, dry
, dgy
, dby
,
1130 int rsign
, gsign
, bsign
;
1131 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1132 unsigned int tr
= to
.red(), tg
= to
.green(), tb
= to
.blue(),
1133 *xt
= xtable
, *yt
= ytable
;
1135 register unsigned int x
, y
;
1137 dry
= drx
= (float) (to
.red() - from
.red());
1138 dgy
= dgx
= (float) (to
.green() - from
.green());
1139 dby
= dbx
= (float) (to
.blue() - from
.blue());
1141 rsign
= (drx
< 0) ? -1 : 1;
1142 gsign
= (dgx
< 0) ? -1 : 1;
1143 bsign
= (dbx
< 0) ? -1 : 1;
1145 xr
= yr
= (drx
/ 2);
1146 xg
= yg
= (dgx
/ 2);
1147 xb
= yb
= (dbx
/ 2);
1154 for (x
= 0; x
< width
; x
++) {
1155 *(xt
++) = (unsigned char) ((xr
< 0) ? -xr
: xr
);
1156 *(xt
++) = (unsigned char) ((xg
< 0) ? -xg
: xg
);
1157 *(xt
++) = (unsigned char) ((xb
< 0) ? -xb
: xb
);
1169 for (y
= 0; y
< height
; y
++) {
1170 *(yt
++) = ((unsigned char) ((yr
< 0) ? -yr
: yr
));
1171 *(yt
++) = ((unsigned char) ((yg
< 0) ? -yg
: yg
));
1172 *(yt
++) = ((unsigned char) ((yb
< 0) ? -yb
: yb
));
1179 // Combine tables to create gradient
1183 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1184 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1185 *(pr
++) = (unsigned char) (tr
- (rsign
* (*(xt
++) + *(yt
))));
1186 *(pg
++) = (unsigned char) (tg
- (gsign
* (*(xt
++) + *(yt
+ 1))));
1187 *(pb
++) = (unsigned char) (tb
- (bsign
* (*(xt
++) + *(yt
+ 2))));
1191 // faked interlacing effect
1192 unsigned char channel
, channel2
;
1194 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1195 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1197 channel
= (unsigned char) (tr
- (rsign
* (*(xt
++) + *(yt
))));
1198 channel2
= (channel
>> 1) + (channel
>> 2);
1199 if (channel2
> channel
) channel2
= 0;
1202 channel
= (unsigned char) (tg
- (gsign
* (*(xt
++) + *(yt
+ 1))));
1203 channel2
= (channel
>> 1) + (channel
>> 2);
1204 if (channel2
> channel
) channel2
= 0;
1207 channel
= (unsigned char) (tb
- (bsign
* (*(xt
++) + *(yt
+ 2))));
1208 channel2
= (channel
>> 1) + (channel
>> 2);
1209 if (channel2
> channel
) channel2
= 0;
1212 channel
= (unsigned char) (tr
- (rsign
* (*(xt
++) + *(yt
))));
1213 channel2
= channel
+ (channel
>> 3);
1214 if (channel2
< channel
) channel2
= ~0;
1217 channel
= (unsigned char) (tg
- (gsign
* (*(xt
++) + *(yt
+ 1))));
1218 channel2
= channel
+ (channel
>> 3);
1219 if (channel2
< channel
) channel2
= ~0;
1222 channel
= (unsigned char) (tb
- (bsign
* (*(xt
++) + *(yt
+ 2))));
1223 channel2
= channel
+ (channel
>> 3);
1224 if (channel2
< channel
) channel2
= ~0;
1233 void Image::rgradient(void) {
1234 // rectangle gradient - based on original dgradient, written by
1235 // Mosfet (mosfet@kde.org)
1236 // adapted from kde sources for Blackbox by Brad Hughes
1238 float drx
, dgx
, dbx
, dry
, dgy
, dby
, xr
, xg
, xb
, yr
, yg
, yb
;
1239 int rsign
, gsign
, bsign
;
1240 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1241 unsigned int tr
= to
.red(), tg
= to
.green(), tb
= to
.blue(),
1242 *xt
= xtable
, *yt
= ytable
;
1244 register unsigned int x
, y
;
1246 dry
= drx
= (float) (to
.red() - from
.red());
1247 dgy
= dgx
= (float) (to
.green() - from
.green());
1248 dby
= dbx
= (float) (to
.blue() - from
.blue());
1250 rsign
= (drx
< 0) ? -2 : 2;
1251 gsign
= (dgx
< 0) ? -2 : 2;
1252 bsign
= (dbx
< 0) ? -2 : 2;
1254 xr
= yr
= (drx
/ 2);
1255 xg
= yg
= (dgx
/ 2);
1256 xb
= yb
= (dbx
/ 2);
1263 for (x
= 0; x
< width
; x
++) {
1264 *(xt
++) = (unsigned char) ((xr
< 0) ? -xr
: xr
);
1265 *(xt
++) = (unsigned char) ((xg
< 0) ? -xg
: xg
);
1266 *(xt
++) = (unsigned char) ((xb
< 0) ? -xb
: xb
);
1278 for (y
= 0; y
< height
; y
++) {
1279 *(yt
++) = ((unsigned char) ((yr
< 0) ? -yr
: yr
));
1280 *(yt
++) = ((unsigned char) ((yg
< 0) ? -yg
: yg
));
1281 *(yt
++) = ((unsigned char) ((yb
< 0) ? -yb
: yb
));
1288 // Combine tables to create gradient
1292 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1293 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1294 *(pr
++) = (unsigned char) (tr
- (rsign
* max(*(xt
++), *(yt
))));
1295 *(pg
++) = (unsigned char) (tg
- (gsign
* max(*(xt
++), *(yt
+ 1))));
1296 *(pb
++) = (unsigned char) (tb
- (bsign
* max(*(xt
++), *(yt
+ 2))));
1300 // faked interlacing effect
1301 unsigned char channel
, channel2
;
1303 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1304 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1306 channel
= (unsigned char) (tr
- (rsign
* max(*(xt
++), *(yt
))));
1307 channel2
= (channel
>> 1) + (channel
>> 2);
1308 if (channel2
> channel
) channel2
= 0;
1311 channel
= (unsigned char) (tg
- (gsign
* max(*(xt
++), *(yt
+ 1))));
1312 channel2
= (channel
>> 1) + (channel
>> 2);
1313 if (channel2
> channel
) channel2
= 0;
1316 channel
= (unsigned char) (tb
- (bsign
* max(*(xt
++), *(yt
+ 2))));
1317 channel2
= (channel
>> 1) + (channel
>> 2);
1318 if (channel2
> channel
) channel2
= 0;
1321 channel
= (unsigned char) (tr
- (rsign
* max(*(xt
++), *(yt
))));
1322 channel2
= channel
+ (channel
>> 3);
1323 if (channel2
< channel
) channel2
= ~0;
1326 channel
= (unsigned char) (tg
- (gsign
* max(*(xt
++), *(yt
+ 1))));
1327 channel2
= channel
+ (channel
>> 3);
1328 if (channel2
< channel
) channel2
= ~0;
1331 channel
= (unsigned char) (tb
- (bsign
* max(*(xt
++), *(yt
+ 2))));
1332 channel2
= channel
+ (channel
>> 3);
1333 if (channel2
< channel
) channel2
= ~0;
1342 void Image::egradient(void) {
1343 // elliptic gradient - based on original dgradient, written by
1344 // Mosfet (mosfet@kde.org)
1345 // adapted from kde sources for Blackbox by Brad Hughes
1347 float drx
, dgx
, dbx
, dry
, dgy
, dby
, yr
, yg
, yb
, xr
, xg
, xb
;
1348 int rsign
, gsign
, bsign
;
1349 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1350 unsigned int *xt
= xtable
, *yt
= ytable
,
1351 tr
= (unsigned long) to
.red(),
1352 tg
= (unsigned long) to
.green(),
1353 tb
= (unsigned long) to
.blue();
1355 register unsigned int x
, y
;
1357 dry
= drx
= (float) (to
.red() - from
.red());
1358 dgy
= dgx
= (float) (to
.green() - from
.green());
1359 dby
= dbx
= (float) (to
.blue() - from
.blue());
1361 rsign
= (drx
< 0) ? -1 : 1;
1362 gsign
= (dgx
< 0) ? -1 : 1;
1363 bsign
= (dbx
< 0) ? -1 : 1;
1365 xr
= yr
= (drx
/ 2);
1366 xg
= yg
= (dgx
/ 2);
1367 xb
= yb
= (dbx
/ 2);
1374 for (x
= 0; x
< width
; x
++) {
1375 *(xt
++) = (unsigned long) (xr
* xr
);
1376 *(xt
++) = (unsigned long) (xg
* xg
);
1377 *(xt
++) = (unsigned long) (xb
* xb
);
1389 for (y
= 0; y
< height
; y
++) {
1390 *(yt
++) = (unsigned long) (yr
* yr
);
1391 *(yt
++) = (unsigned long) (yg
* yg
);
1392 *(yt
++) = (unsigned long) (yb
* yb
);
1399 // Combine tables to create gradient
1403 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1404 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1405 *(pr
++) = (unsigned char)
1406 (tr
- (rsign
* control
->getSqrt(*(xt
++) + *(yt
))));
1407 *(pg
++) = (unsigned char)
1408 (tg
- (gsign
* control
->getSqrt(*(xt
++) + *(yt
+ 1))));
1409 *(pb
++) = (unsigned char)
1410 (tb
- (bsign
* control
->getSqrt(*(xt
++) + *(yt
+ 2))));
1414 // faked interlacing effect
1415 unsigned char channel
, channel2
;
1417 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1418 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1420 channel
= (unsigned char)
1421 (tr
- (rsign
* control
->getSqrt(*(xt
++) + *(yt
))));
1422 channel2
= (channel
>> 1) + (channel
>> 2);
1423 if (channel2
> channel
) channel2
= 0;
1426 channel
= (unsigned char)
1427 (tg
- (gsign
* control
->getSqrt(*(xt
++) + *(yt
+ 1))));
1428 channel2
= (channel
>> 1) + (channel
>> 2);
1429 if (channel2
> channel
) channel2
= 0;
1432 channel
= (unsigned char)
1433 (tb
- (bsign
* control
->getSqrt(*(xt
++) + *(yt
+ 2))));
1434 channel2
= (channel
>> 1) + (channel
>> 2);
1435 if (channel2
> channel
) channel2
= 0;
1438 channel
= (unsigned char)
1439 (tr
- (rsign
* control
->getSqrt(*(xt
++) + *(yt
))));
1440 channel2
= channel
+ (channel
>> 3);
1441 if (channel2
< channel
) channel2
= ~0;
1444 channel
= (unsigned char)
1445 (tg
- (gsign
* control
->getSqrt(*(xt
++) + *(yt
+ 1))));
1446 channel2
= channel
+ (channel
>> 3);
1447 if (channel2
< channel
) channel2
= ~0;
1450 channel
= (unsigned char)
1451 (tb
- (bsign
* control
->getSqrt(*(xt
++) + *(yt
+ 2))));
1452 channel2
= channel
+ (channel
>> 3);
1453 if (channel2
< channel
) channel2
= ~0;
1462 void Image::pcgradient(void) {
1463 // pipe cross gradient - based on original dgradient, written by
1464 // Mosfet (mosfet@kde.org)
1465 // adapted from kde sources for Blackbox by Brad Hughes
1467 float drx
, dgx
, dbx
, dry
, dgy
, dby
, xr
, xg
, xb
, yr
, yg
, yb
;
1468 int rsign
, gsign
, bsign
;
1469 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1470 unsigned int *xt
= xtable
, *yt
= ytable
,
1475 register unsigned int x
, y
;
1477 dry
= drx
= (float) (to
.red() - from
.red());
1478 dgy
= dgx
= (float) (to
.green() - from
.green());
1479 dby
= dbx
= (float) (to
.blue() - from
.blue());
1481 rsign
= (drx
< 0) ? -2 : 2;
1482 gsign
= (dgx
< 0) ? -2 : 2;
1483 bsign
= (dbx
< 0) ? -2 : 2;
1485 xr
= yr
= (drx
/ 2);
1486 xg
= yg
= (dgx
/ 2);
1487 xb
= yb
= (dbx
/ 2);
1494 for (x
= 0; x
< width
; x
++) {
1495 *(xt
++) = (unsigned char) ((xr
< 0) ? -xr
: xr
);
1496 *(xt
++) = (unsigned char) ((xg
< 0) ? -xg
: xg
);
1497 *(xt
++) = (unsigned char) ((xb
< 0) ? -xb
: xb
);
1509 for (y
= 0; y
< height
; y
++) {
1510 *(yt
++) = ((unsigned char) ((yr
< 0) ? -yr
: yr
));
1511 *(yt
++) = ((unsigned char) ((yg
< 0) ? -yg
: yg
));
1512 *(yt
++) = ((unsigned char) ((yb
< 0) ? -yb
: yb
));
1519 // Combine tables to create gradient
1522 // normal pcgradient
1523 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1524 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1525 *(pr
++) = (unsigned char) (tr
- (rsign
* min(*(xt
++), *(yt
))));
1526 *(pg
++) = (unsigned char) (tg
- (gsign
* min(*(xt
++), *(yt
+ 1))));
1527 *(pb
++) = (unsigned char) (tb
- (bsign
* min(*(xt
++), *(yt
+ 2))));
1531 // faked interlacing effect
1532 unsigned char channel
, channel2
;
1534 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1535 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1537 channel
= (unsigned char) (tr
- (rsign
* min(*(xt
++), *(yt
))));
1538 channel2
= (channel
>> 1) + (channel
>> 2);
1539 if (channel2
> channel
) channel2
= 0;
1542 channel
= (unsigned char) (tg
- (bsign
* min(*(xt
++), *(yt
+ 1))));
1543 channel2
= (channel
>> 1) + (channel
>> 2);
1544 if (channel2
> channel
) channel2
= 0;
1547 channel
= (unsigned char) (tb
- (gsign
* min(*(xt
++), *(yt
+ 2))));
1548 channel2
= (channel
>> 1) + (channel
>> 2);
1549 if (channel2
> channel
) channel2
= 0;
1552 channel
= (unsigned char) (tr
- (rsign
* min(*(xt
++), *(yt
))));
1553 channel2
= channel
+ (channel
>> 3);
1554 if (channel2
< channel
) channel2
= ~0;
1557 channel
= (unsigned char) (tg
- (gsign
* min(*(xt
++), *(yt
+ 1))));
1558 channel2
= channel
+ (channel
>> 3);
1559 if (channel2
< channel
) channel2
= ~0;
1562 channel
= (unsigned char) (tb
- (bsign
* min(*(xt
++), *(yt
+ 2))));
1563 channel2
= channel
+ (channel
>> 3);
1564 if (channel2
< channel
) channel2
= ~0;
1573 void Image::cdgradient(void) {
1574 // cross diagonal gradient - based on original dgradient, written by
1575 // Mosfet (mosfet@kde.org)
1576 // adapted from kde sources for Blackbox by Brad Hughes
1578 float drx
, dgx
, dbx
, dry
, dgy
, dby
, yr
= 0.0, yg
= 0.0, yb
= 0.0,
1579 xr
= (float) from
.red(),
1580 xg
= (float) from
.green(),
1581 xb
= (float) from
.blue();
1582 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1583 unsigned int w
= width
* 2, h
= height
* 2, *xt
, *yt
;
1585 register unsigned int x
, y
;
1587 dry
= drx
= (float) (to
.red() - from
.red());
1588 dgy
= dgx
= (float) (to
.green() - from
.green());
1589 dby
= dbx
= (float) (to
.blue() - from
.blue());
1596 for (xt
= (xtable
+ (width
* 3) - 1), x
= 0; x
< width
; x
++) {
1597 *(xt
--) = (unsigned char) xb
;
1598 *(xt
--) = (unsigned char) xg
;
1599 *(xt
--) = (unsigned char) xr
;
1611 for (yt
= ytable
, y
= 0; y
< height
; y
++) {
1612 *(yt
++) = (unsigned char) yr
;
1613 *(yt
++) = (unsigned char) yg
;
1614 *(yt
++) = (unsigned char) yb
;
1621 // Combine tables to create gradient
1624 // normal cdgradient
1625 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1626 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1627 *(pr
++) = *(xt
++) + *(yt
);
1628 *(pg
++) = *(xt
++) + *(yt
+ 1);
1629 *(pb
++) = *(xt
++) + *(yt
+ 2);
1633 // faked interlacing effect
1634 unsigned char channel
, channel2
;
1636 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1637 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1639 channel
= *(xt
++) + *(yt
);
1640 channel2
= (channel
>> 1) + (channel
>> 2);
1641 if (channel2
> channel
) channel2
= 0;
1644 channel
= *(xt
++) + *(yt
+ 1);
1645 channel2
= (channel
>> 1) + (channel
>> 2);
1646 if (channel2
> channel
) channel2
= 0;
1649 channel
= *(xt
++) + *(yt
+ 2);
1650 channel2
= (channel
>> 1) + (channel
>> 2);
1651 if (channel2
> channel
) channel2
= 0;
1654 channel
= *(xt
++) + *(yt
);
1655 channel2
= channel
+ (channel
>> 3);
1656 if (channel2
< channel
) channel2
= ~0;
1659 channel
= *(xt
++) + *(yt
+ 1);
1660 channel2
= channel
+ (channel
>> 3);
1661 if (channel2
< channel
) channel2
= ~0;
1664 channel
= *(xt
++) + *(yt
+ 2);
1665 channel2
= channel
+ (channel
>> 3);
1666 if (channel2
< channel
) channel2
= ~0;
This page took 0.120423 seconds and 4 git commands to generate.