]>
Dogcows Code - chaz/openbox/blob - src/image.cc
1 // -*- mode: C++; indent-tabs-mode: nil; -*-
2 // Image.cc for Blackbox - an X11 Window manager
3 // Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
4 // Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
6 // Permission is hereby granted, free of charge, to any person obtaining a
7 // copy of this software and associated documentation files (the "Software"),
8 // to deal in the Software without restriction, including without limitation
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 // and/or sell copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following conditions:
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 // DEALINGS IN THE SOFTWARE.
25 # include "../config.h"
26 #endif // HAVE_CONFIG_H
30 #endif // HAVE_STDIO_H
36 #include "blackbox.hh"
37 #include "basedisplay.hh"
43 BImage::BImage(BImageControl
*c
, int w
, int h
) {
46 width
= (w
> 0) ? w
: 1;
47 height
= (h
> 0) ? h
: 1;
49 red
= new unsigned char[width
* height
];
50 green
= new unsigned char[width
* height
];
51 blue
= new unsigned char[width
* height
];
53 xtable
= ytable
= (unsigned int *) 0;
55 cpc
= control
->getColorsPerChannel();
58 control
->getColorTables(&red_table
, &green_table
, &blue_table
,
59 &red_offset
, &green_offset
, &blue_offset
,
60 &red_bits
, &green_bits
, &blue_bits
);
62 if (control
->getVisual()->c_class
!= TrueColor
)
63 control
->getXColorTable(&colors
, &ncolors
);
67 BImage::~BImage(void) {
74 Pixmap
BImage::render(const BTexture
&texture
) {
75 if (texture
.texture() & BTexture::Parent_Relative
)
76 return ParentRelative
;
77 else if (texture
.texture() & BTexture::Solid
)
78 return render_solid(texture
);
79 else if (texture
.texture() & BTexture::Gradient
)
80 return render_gradient(texture
);
85 Pixmap
BImage::render_solid(const BTexture
&texture
) {
86 Pixmap pixmap
= XCreatePixmap(control
->getBaseDisplay()->getXDisplay(),
87 control
->getDrawable(), width
,
88 height
, control
->getDepth());
90 fprintf(stderr
, "BImage::render_solid: error creating pixmap\n");
94 Display
*display
= control
->getBaseDisplay()->getXDisplay();
96 BPen
pen(texture
.color());
97 BPen
penlight(texture
.lightColor());
98 BPen
penshadow(texture
.shadowColor());
100 XFillRectangle(display
, pixmap
, pen
.gc(), 0, 0, width
, height
);
102 if (texture
.texture() & BTexture::Interlaced
) {
103 BPen
peninterlace(texture
.colorTo());
104 for (unsigned int i
= 0; i
< height
; i
+= 2)
105 XDrawLine(display
, pixmap
, peninterlace
.gc(), 0, i
, width
, i
);
108 int left
= 0, top
= 0, right
= width
- 1, bottom
= height
- 1;
110 if (texture
.texture() & BTexture::Border
) {
111 BPen
penborder(texture
.borderColor());
112 XDrawRectangle(display
, pixmap
, penborder
.gc(),
113 left
, top
, right
, bottom
);
116 if (texture
.texture() & BTexture::Bevel1
) {
117 if (texture
.texture() & BTexture::Raised
) {
118 XDrawLine(display
, pixmap
, penshadow
.gc(),
119 left
, bottom
, right
, bottom
);
120 XDrawLine(display
, pixmap
, penshadow
.gc(),
121 right
, bottom
, right
, top
);
123 XDrawLine(display
, pixmap
, penlight
.gc(),
124 left
, top
, right
, top
);
125 XDrawLine(display
, pixmap
, penlight
.gc(),
126 left
, bottom
, left
, top
);
127 } else if (texture
.texture() & BTexture::Sunken
) {
128 XDrawLine(display
, pixmap
, penlight
.gc(),
129 left
, bottom
, right
, bottom
);
130 XDrawLine(display
, pixmap
, penlight
.gc(),
131 right
, bottom
, right
, top
);
133 XDrawLine(display
, pixmap
, penshadow
.gc(),
134 left
, top
, right
, top
);
135 XDrawLine(display
, pixmap
, penshadow
.gc(),
136 left
, bottom
, left
, top
);
138 } else if (texture
.texture() & BTexture::Bevel2
) {
139 if (texture
.texture() & BTexture::Raised
) {
140 XDrawLine(display
, pixmap
, penshadow
.gc(),
141 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
142 XDrawLine(display
, pixmap
, penshadow
.gc(),
143 right
- 2, bottom
- 2, right
- 2, top
+ 1);
145 XDrawLine(display
, pixmap
, penlight
.gc(),
146 left
+ 1, top
+ 1, right
- 2, top
+ 1);
147 XDrawLine(display
, pixmap
, penlight
.gc(),
148 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
149 } else if (texture
.texture() & BTexture::Sunken
) {
150 XDrawLine(display
, pixmap
, penlight
.gc(),
151 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
152 XDrawLine(display
, pixmap
, penlight
.gc(),
153 right
- 2, bottom
- 2, right
- 2, top
+ 1);
155 XDrawLine(display
, pixmap
, penshadow
.gc(),
156 left
+ 1, top
+ 1, right
- 2, top
+ 1);
157 XDrawLine(display
, pixmap
, penshadow
.gc(),
158 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
166 Pixmap
BImage::render_gradient(const BTexture
&texture
) {
167 bool inverted
= False
;
169 interlaced
= texture
.texture() & BTexture::Interlaced
;
171 if (texture
.texture() & BTexture::Sunken
) {
172 from
= texture
.colorTo();
173 to
= texture
.color();
175 if (! (texture
.texture() & BTexture::Invert
)) inverted
= True
;
177 from
= texture
.color();
178 to
= texture
.colorTo();
180 if (texture
.texture() & BTexture::Invert
) inverted
= True
;
183 control
->getGradientBuffers(width
, height
, &xtable
, &ytable
);
185 if (texture
.texture() & BTexture::Diagonal
) dgradient();
186 else if (texture
.texture() & BTexture::Elliptic
) egradient();
187 else if (texture
.texture() & BTexture::Horizontal
) hgradient();
188 else if (texture
.texture() & BTexture::Pyramid
) pgradient();
189 else if (texture
.texture() & BTexture::Rectangle
) rgradient();
190 else if (texture
.texture() & BTexture::Vertical
) vgradient();
191 else if (texture
.texture() & BTexture::CrossDiagonal
) cdgradient();
192 else if (texture
.texture() & BTexture::PipeCross
) pcgradient();
194 if (texture
.texture() & BTexture::Bevel1
) bevel1();
195 else if (texture
.texture() & BTexture::Bevel2
) bevel2();
197 if (texture
.texture() & BTexture::Border
) border(texture
);
199 if (inverted
) invert();
201 return renderPixmap();
206 static const unsigned char dither4
[4][4] = {
215 * Helper function for TrueColorDither and renderXImage
217 * This handles the proper setting of the image data based on the image depth
218 * and the machine's byte ordering
221 void assignPixelData(unsigned int bit_depth
, unsigned char **data
,
222 unsigned long pixel
) {
223 unsigned char *pixel_data
= *data
;
226 *pixel_data
++ = pixel
;
229 case 16: // 16bpp LSB
230 *pixel_data
++ = pixel
;
231 *pixel_data
++ = pixel
>> 8;
234 case 17: // 16bpp MSB
235 *pixel_data
++ = pixel
>> 8;
236 *pixel_data
++ = pixel
;
239 case 24: // 24bpp LSB
240 *pixel_data
++ = pixel
;
241 *pixel_data
++ = pixel
>> 8;
242 *pixel_data
++ = pixel
>> 16;
245 case 25: // 24bpp MSB
246 *pixel_data
++ = pixel
>> 16;
247 *pixel_data
++ = pixel
>> 8;
248 *pixel_data
++ = pixel
;
251 case 32: // 32bpp LSB
252 *pixel_data
++ = pixel
;
253 *pixel_data
++ = pixel
>> 8;
254 *pixel_data
++ = pixel
>> 16;
255 *pixel_data
++ = pixel
>> 24;
258 case 33: // 32bpp MSB
259 *pixel_data
++ = pixel
>> 24;
260 *pixel_data
++ = pixel
>> 16;
261 *pixel_data
++ = pixel
>> 8;
262 *pixel_data
++ = pixel
;
265 *data
= pixel_data
; // assign back so we don't lose our place
269 // algorithm: ordered dithering... many many thanks to rasterman
270 // (raster@rasterman.com) for telling me about this... portions of this
271 // code is based off of his code in Imlib
272 void BImage::TrueColorDither(unsigned int bit_depth
, int bytes_per_line
,
273 unsigned char *pixel_data
) {
274 unsigned int x
, y
, dithx
, dithy
, r
, g
, b
, er
, eg
, eb
, offset
;
275 unsigned char *ppixel_data
= pixel_data
;
278 for (y
= 0, offset
= 0; y
< height
; y
++) {
281 for (x
= 0; x
< width
; x
++, offset
++) {
287 er
= r
& (red_bits
- 1);
288 eg
= g
& (green_bits
- 1);
289 eb
= b
& (blue_bits
- 1);
295 if ((dither4
[dithy
][dithx
] < er
) && (r
< red_table
[255])) r
++;
296 if ((dither4
[dithy
][dithx
] < eg
) && (g
< green_table
[255])) g
++;
297 if ((dither4
[dithy
][dithx
] < eb
) && (b
< blue_table
[255])) b
++;
299 pixel
= (r
<< red_offset
) | (g
<< green_offset
) | (b
<< blue_offset
);
300 assignPixelData(bit_depth
, &pixel_data
, pixel
);
303 pixel_data
= (ppixel_data
+= bytes_per_line
);
308 const static unsigned char dither8
[8][8] = {
309 { 0, 32, 8, 40, 2, 34, 10, 42},
310 { 48, 16, 56, 24, 50, 18, 58, 26},
311 { 12, 44, 4, 36, 14, 46, 6, 38},
312 { 60, 28, 52, 20, 62, 30, 54, 22},
313 { 3, 35, 11, 43, 1, 33, 9, 41},
314 { 51, 19, 59, 27, 49, 17, 57, 25},
315 { 15, 47, 7, 39, 13, 45, 5, 37},
316 { 63, 31, 55, 23, 61, 29, 53, 21}
319 void BImage::OrderedPseudoColorDither(int bytes_per_line
,
320 unsigned char *pixel_data
) {
321 unsigned int x
, y
, dithx
, dithy
, r
, g
, b
, er
, eg
, eb
, offset
;
323 unsigned char *ppixel_data
= pixel_data
;
325 for (y
= 0, offset
= 0; y
< height
; y
++) {
328 for (x
= 0; x
< width
; x
++, offset
++) {
335 er
= r
& (red_bits
- 1);
336 eg
= g
& (green_bits
- 1);
337 eb
= b
& (blue_bits
- 1);
343 if ((dither8
[dithy
][dithx
] < er
) && (r
< red_table
[255])) r
++;
344 if ((dither8
[dithy
][dithx
] < eg
) && (g
< green_table
[255])) g
++;
345 if ((dither8
[dithy
][dithx
] < eb
) && (b
< blue_table
[255])) b
++;
347 pixel
= (r
* cpccpc
) + (g
* cpc
) + b
;
348 *(pixel_data
++) = colors
[pixel
].pixel
;
351 pixel_data
= (ppixel_data
+= bytes_per_line
);
356 void BImage::PseudoColorDither(int bytes_per_line
, unsigned char *pixel_data
) {
358 *rerr
= new short[width
+ 2],
359 *gerr
= new short[width
+ 2],
360 *berr
= new short[width
+ 2],
361 *nrerr
= new short[width
+ 2],
362 *ngerr
= new short[width
+ 2],
363 *nberr
= new short[width
+ 2];
365 int rr
, gg
, bb
, rer
, ger
, ber
;
366 int dd
= 255 / control
->getColorsPerChannel();
367 unsigned int x
, y
, r
, g
, b
, offset
;
369 unsigned char *ppixel_data
= pixel_data
;
371 for (x
= 0; x
< width
; x
++) {
372 *(rerr
+ x
) = *(red
+ x
);
373 *(gerr
+ x
) = *(green
+ x
);
374 *(berr
+ x
) = *(blue
+ x
);
377 *(rerr
+ x
) = *(gerr
+ x
) = *(berr
+ x
) = 0;
379 for (y
= 0, offset
= 0; y
< height
; y
++) {
380 if (y
< (height
- 1)) {
381 int i
= offset
+ width
;
382 for (x
= 0; x
< width
; x
++, i
++) {
383 *(nrerr
+ x
) = *(red
+ i
);
384 *(ngerr
+ x
) = *(green
+ i
);
385 *(nberr
+ x
) = *(blue
+ i
);
388 *(nrerr
+ x
) = *(red
+ (--i
));
389 *(ngerr
+ x
) = *(green
+ i
);
390 *(nberr
+ x
) = *(blue
+ i
);
393 for (x
= 0; x
< width
; x
++) {
398 if (rr
> 255) rr
= 255; else if (rr
< 0) rr
= 0;
399 if (gg
> 255) gg
= 255; else if (gg
< 0) gg
= 0;
400 if (bb
> 255) bb
= 255; else if (bb
< 0) bb
= 0;
406 rer
= rerr
[x
] - r
*dd
;
407 ger
= gerr
[x
] - g
*dd
;
408 ber
= berr
[x
] - b
*dd
;
410 pixel
= (r
* cpccpc
) + (g
* cpc
) + b
;
411 *pixel_data
++ = colors
[pixel
].pixel
;
426 pixel_data
= (ppixel_data
+= bytes_per_line
);
449 XImage
*BImage::renderXImage(void) {
451 XCreateImage(control
->getBaseDisplay()->getXDisplay(),
452 control
->getVisual(), control
->getDepth(), ZPixmap
, 0, 0,
453 width
, height
, 32, 0);
456 fprintf(stderr
, "BImage::renderXImage: error creating XImage\n");
461 image
->data
= (char *) 0;
463 unsigned char *d
= new unsigned char[image
->bytes_per_line
* (height
+ 1)];
465 unsigned int o
= image
->bits_per_pixel
+
466 ((image
->byte_order
== MSBFirst
) ? 1 : 0);
468 bool unsupported
= False
;
470 if (control
->doDither() && width
> 1 && height
> 1) {
471 switch (control
->getVisual()->c_class
) {
473 TrueColorDither(o
, image
->bytes_per_line
, d
);
479 OrderedPseudoColorDither(image
->bytes_per_line
, d
);
481 PseudoColorDither(image
->bytes_per_line
, d
);
490 unsigned int x
, y
, r
, g
, b
, offset
;
491 unsigned char *pixel_data
= d
, *ppixel_data
= d
;
494 switch (control
->getVisual()->c_class
) {
497 for (y
= 0, offset
= 0; y
< height
; ++y
) {
498 for (x
= 0; x
< width
; ++x
, ++offset
) {
499 r
= red_table
[red
[offset
]];
500 g
= green_table
[green
[offset
]];
501 b
= blue_table
[blue
[offset
]];
503 pixel
= (r
* cpccpc
) + (g
* cpc
) + b
;
504 *pixel_data
++ = colors
[pixel
].pixel
;
507 pixel_data
= (ppixel_data
+= image
->bytes_per_line
);
513 for (y
= 0, offset
= 0; y
< height
; y
++) {
514 for (x
= 0; x
< width
; x
++, offset
++) {
515 r
= red_table
[red
[offset
]];
516 g
= green_table
[green
[offset
]];
517 b
= blue_table
[blue
[offset
]];
519 pixel
= (r
<< red_offset
) | (g
<< green_offset
) | (b
<< blue_offset
);
520 assignPixelData(o
, &pixel_data
, pixel
);
523 pixel_data
= (ppixel_data
+= image
->bytes_per_line
);
530 for (y
= 0, offset
= 0; y
< height
; y
++) {
531 for (x
= 0; x
< width
; x
++, offset
++) {
532 r
= *(red_table
+ *(red
+ offset
));
533 g
= *(green_table
+ *(green
+ offset
));
534 b
= *(blue_table
+ *(blue
+ offset
));
536 g
= ((r
* 30) + (g
* 59) + (b
* 11)) / 100;
537 *pixel_data
++ = colors
[g
].pixel
;
540 pixel_data
= (ppixel_data
+= image
->bytes_per_line
);
551 fprintf(stderr
, "BImage::renderXImage: unsupported visual\n");
553 XDestroyImage(image
);
557 image
->data
= (char *) d
;
563 Pixmap
BImage::renderPixmap(void) {
565 XCreatePixmap(control
->getBaseDisplay()->getXDisplay(),
566 control
->getDrawable(), width
, height
, control
->getDepth());
568 if (pixmap
== None
) {
569 fprintf(stderr
, "BImage::renderPixmap: error creating pixmap\n");
573 XImage
*image
= renderXImage();
576 XFreePixmap(control
->getBaseDisplay()->getXDisplay(), pixmap
);
581 XDestroyImage(image
);
582 XFreePixmap(control
->getBaseDisplay()->getXDisplay(), pixmap
);
586 XPutImage(control
->getBaseDisplay()->getXDisplay(), pixmap
,
587 DefaultGC(control
->getBaseDisplay()->getXDisplay(),
588 control
->getScreenInfo()->getScreenNumber()),
589 image
, 0, 0, 0, 0, width
, height
);
592 delete [] image
->data
;
596 XDestroyImage(image
);
602 void BImage::bevel1(void) {
603 if (width
> 2 && height
> 2) {
604 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
606 register unsigned char r
, g
, b
, rr
,gg
,bb
;
607 register unsigned int w
= width
, h
= height
- 1, wh
= w
* h
;
625 rr
= (r
>> 2) + (r
>> 1);
628 gg
= (g
>> 2) + (g
>> 1);
631 bb
= (b
>> 2) + (b
>> 1);
654 rr
= (r
>> 2) + (r
>> 1);
657 gg
= (g
>> 2) + (g
>> 1);
660 bb
= (b
>> 2) + (b
>> 1);
691 rr
= (r
>> 2) + (r
>> 1);
694 gg
= (g
>> 2) + (g
>> 1);
697 bb
= (b
>> 2) + (b
>> 1);
724 rr
= (r
>> 2) + (r
>> 1);
727 gg
= (g
>> 2) + (g
>> 1);
730 bb
= (b
>> 2) + (b
>> 1);
740 void BImage::bevel2(void) {
741 if (width
> 4 && height
> 4) {
742 unsigned char r
, g
, b
, rr
,gg
,bb
, *pr
= red
+ width
+ 1,
743 *pg
= green
+ width
+ 1, *pb
= blue
+ width
+ 1;
744 unsigned int w
= width
- 2, h
= height
- 1, wh
= width
* (height
- 3);
762 rr
= (r
>> 2) + (r
>> 1);
765 gg
= (g
>> 2) + (g
>> 1);
768 bb
= (b
>> 2) + (b
>> 1);
800 rr
= (r
>> 2) + (r
>> 1);
803 gg
= (g
>> 2) + (g
>> 1);
806 bb
= (b
>> 2) + (b
>> 1);
819 void BImage::border(const BTexture
&texture
) {
820 if (width
< 2 || height
< 2) return;
822 register unsigned int i
;
823 int r
= texture
.borderColor().red(),
824 g
= texture
.borderColor().green(),
825 b
= texture
.borderColor().blue();
827 unsigned char *pr
, *pg
, *pb
;
833 for (i
= 0; i
< width
; ++i
) {
840 // left and right lines (pr,pg,pb are already lined up)
841 for (i
= 1; i
< height
- 1; ++i
) {
854 // bottom line (pr,pg,pb are already lined up)
855 for (i
= 0; i
< width
; ++i
) {
863 void BImage::invert(void) {
864 register unsigned int i
, j
, wh
= (width
* height
) - 1;
867 for (i
= 0, j
= wh
; j
> i
; j
--, i
++) {
869 *(red
+ j
) = *(red
+ i
);
873 *(green
+ j
) = *(green
+ i
);
877 *(blue
+ j
) = *(blue
+ i
);
883 void BImage::dgradient(void) {
884 // diagonal gradient code was written by Mike Cole <mike@mydot.com>
885 // modified for interlacing by Brad Hughes
887 float drx
, dgx
, dbx
, dry
, dgy
, dby
, yr
= 0.0, yg
= 0.0, yb
= 0.0,
888 xr
= (float) from
.red(),
889 xg
= (float) from
.green(),
890 xb
= (float) from
.blue();
891 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
892 unsigned int w
= width
* 2, h
= height
* 2, *xt
= xtable
, *yt
= ytable
;
894 register unsigned int x
, y
;
896 dry
= drx
= (float) (to
.red() - from
.red());
897 dgy
= dgx
= (float) (to
.green() - from
.green());
898 dby
= dbx
= (float) (to
.blue() - from
.blue());
905 for (x
= 0; x
< width
; x
++) {
906 *(xt
++) = (unsigned char) (xr
);
907 *(xt
++) = (unsigned char) (xg
);
908 *(xt
++) = (unsigned char) (xb
);
920 for (y
= 0; y
< height
; y
++) {
921 *(yt
++) = ((unsigned char) yr
);
922 *(yt
++) = ((unsigned char) yg
);
923 *(yt
++) = ((unsigned char) yb
);
930 // Combine tables to create gradient
934 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
935 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
936 *(pr
++) = *(xt
++) + *(yt
);
937 *(pg
++) = *(xt
++) + *(yt
+ 1);
938 *(pb
++) = *(xt
++) + *(yt
+ 2);
942 // faked interlacing effect
943 unsigned char channel
, channel2
;
945 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
946 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
948 channel
= *(xt
++) + *(yt
);
949 channel2
= (channel
>> 1) + (channel
>> 2);
950 if (channel2
> channel
) channel2
= 0;
953 channel
= *(xt
++) + *(yt
+ 1);
954 channel2
= (channel
>> 1) + (channel
>> 2);
955 if (channel2
> channel
) channel2
= 0;
958 channel
= *(xt
++) + *(yt
+ 2);
959 channel2
= (channel
>> 1) + (channel
>> 2);
960 if (channel2
> channel
) channel2
= 0;
963 channel
= *(xt
++) + *(yt
);
964 channel2
= channel
+ (channel
>> 3);
965 if (channel2
< channel
) channel2
= ~0;
968 channel
= *(xt
++) + *(yt
+ 1);
969 channel2
= channel
+ (channel
>> 3);
970 if (channel2
< channel
) channel2
= ~0;
973 channel
= *(xt
++) + *(yt
+ 2);
974 channel2
= channel
+ (channel
>> 3);
975 if (channel2
< channel
) channel2
= ~0;
984 void BImage::hgradient(void) {
986 xr
= (float) from
.red(),
987 xg
= (float) from
.green(),
988 xb
= (float) from
.blue();
989 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
991 register unsigned int x
, y
;
993 drx
= (float) (to
.red() - from
.red());
994 dgx
= (float) (to
.green() - from
.green());
995 dbx
= (float) (to
.blue() - from
.blue());
1001 if (interlaced
&& height
> 2) {
1002 // faked interlacing effect
1003 unsigned char channel
, channel2
;
1005 for (x
= 0; x
< width
; x
++, pr
++, pg
++, pb
++) {
1006 channel
= (unsigned char) xr
;
1007 channel2
= (channel
>> 1) + (channel
>> 2);
1008 if (channel2
> channel
) channel2
= 0;
1011 channel
= (unsigned char) xg
;
1012 channel2
= (channel
>> 1) + (channel
>> 2);
1013 if (channel2
> channel
) channel2
= 0;
1016 channel
= (unsigned char) xb
;
1017 channel2
= (channel
>> 1) + (channel
>> 2);
1018 if (channel2
> channel
) channel2
= 0;
1022 channel
= (unsigned char) xr
;
1023 channel2
= channel
+ (channel
>> 3);
1024 if (channel2
< channel
) channel2
= ~0;
1025 *(pr
+ width
) = channel2
;
1027 channel
= (unsigned char) xg
;
1028 channel2
= channel
+ (channel
>> 3);
1029 if (channel2
< channel
) channel2
= ~0;
1030 *(pg
+ width
) = channel2
;
1032 channel
= (unsigned char) xb
;
1033 channel2
= channel
+ (channel
>> 3);
1034 if (channel2
< channel
) channel2
= ~0;
1035 *(pb
+ width
) = channel2
;
1048 for (y
= 2; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1049 if (y
& 1) offset
= width
; else offset
= 0;
1051 memcpy(pr
, (red
+ offset
), width
);
1052 memcpy(pg
, (green
+ offset
), width
);
1053 memcpy(pb
, (blue
+ offset
), width
);
1057 for (x
= 0; x
< width
; x
++) {
1058 *(pr
++) = (unsigned char) (xr
);
1059 *(pg
++) = (unsigned char) (xg
);
1060 *(pb
++) = (unsigned char) (xb
);
1067 for (y
= 1; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1068 memcpy(pr
, red
, width
);
1069 memcpy(pg
, green
, width
);
1070 memcpy(pb
, blue
, width
);
1076 void BImage::vgradient(void) {
1077 float dry
, dgy
, dby
,
1078 yr
= (float) from
.red(),
1079 yg
= (float) from
.green(),
1080 yb
= (float) from
.blue();
1081 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1083 register unsigned int y
;
1085 dry
= (float) (to
.red() - from
.red());
1086 dgy
= (float) (to
.green() - from
.green());
1087 dby
= (float) (to
.blue() - from
.blue());
1094 // faked interlacing effect
1095 unsigned char channel
, channel2
;
1097 for (y
= 0; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1099 channel
= (unsigned char) yr
;
1100 channel2
= (channel
>> 1) + (channel
>> 2);
1101 if (channel2
> channel
) channel2
= 0;
1102 memset(pr
, channel2
, width
);
1104 channel
= (unsigned char) yg
;
1105 channel2
= (channel
>> 1) + (channel
>> 2);
1106 if (channel2
> channel
) channel2
= 0;
1107 memset(pg
, channel2
, width
);
1109 channel
= (unsigned char) yb
;
1110 channel2
= (channel
>> 1) + (channel
>> 2);
1111 if (channel2
> channel
) channel2
= 0;
1112 memset(pb
, channel2
, width
);
1114 channel
= (unsigned char) yr
;
1115 channel2
= channel
+ (channel
>> 3);
1116 if (channel2
< channel
) channel2
= ~0;
1117 memset(pr
, channel2
, width
);
1119 channel
= (unsigned char) yg
;
1120 channel2
= channel
+ (channel
>> 3);
1121 if (channel2
< channel
) channel2
= ~0;
1122 memset(pg
, channel2
, width
);
1124 channel
= (unsigned char) yb
;
1125 channel2
= channel
+ (channel
>> 3);
1126 if (channel2
< channel
) channel2
= ~0;
1127 memset(pb
, channel2
, width
);
1136 for (y
= 0; y
< height
; y
++, pr
+= width
, pg
+= width
, pb
+= width
) {
1137 memset(pr
, (unsigned char) yr
, width
);
1138 memset(pg
, (unsigned char) yg
, width
);
1139 memset(pb
, (unsigned char) yb
, width
);
1149 void BImage::pgradient(void) {
1150 // pyramid gradient - based on original dgradient, written by
1151 // Mosfet (mosfet@kde.org)
1152 // adapted from kde sources for Blackbox by Brad Hughes
1154 float yr
, yg
, yb
, drx
, dgx
, dbx
, dry
, dgy
, dby
,
1156 int rsign
, gsign
, bsign
;
1157 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1158 unsigned int tr
= to
.red(), tg
= to
.green(), tb
= to
.blue(),
1159 *xt
= xtable
, *yt
= ytable
;
1161 register unsigned int x
, y
;
1163 dry
= drx
= (float) (to
.red() - from
.red());
1164 dgy
= dgx
= (float) (to
.green() - from
.green());
1165 dby
= dbx
= (float) (to
.blue() - from
.blue());
1167 rsign
= (drx
< 0) ? -1 : 1;
1168 gsign
= (dgx
< 0) ? -1 : 1;
1169 bsign
= (dbx
< 0) ? -1 : 1;
1171 xr
= yr
= (drx
/ 2);
1172 xg
= yg
= (dgx
/ 2);
1173 xb
= yb
= (dbx
/ 2);
1180 for (x
= 0; x
< width
; x
++) {
1181 *(xt
++) = (unsigned char) ((xr
< 0) ? -xr
: xr
);
1182 *(xt
++) = (unsigned char) ((xg
< 0) ? -xg
: xg
);
1183 *(xt
++) = (unsigned char) ((xb
< 0) ? -xb
: xb
);
1195 for (y
= 0; y
< height
; y
++) {
1196 *(yt
++) = ((unsigned char) ((yr
< 0) ? -yr
: yr
));
1197 *(yt
++) = ((unsigned char) ((yg
< 0) ? -yg
: yg
));
1198 *(yt
++) = ((unsigned char) ((yb
< 0) ? -yb
: yb
));
1205 // Combine tables to create gradient
1209 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1210 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1211 *(pr
++) = (unsigned char) (tr
- (rsign
* (*(xt
++) + *(yt
))));
1212 *(pg
++) = (unsigned char) (tg
- (gsign
* (*(xt
++) + *(yt
+ 1))));
1213 *(pb
++) = (unsigned char) (tb
- (bsign
* (*(xt
++) + *(yt
+ 2))));
1217 // faked interlacing effect
1218 unsigned char channel
, channel2
;
1220 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1221 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1223 channel
= (unsigned char) (tr
- (rsign
* (*(xt
++) + *(yt
))));
1224 channel2
= (channel
>> 1) + (channel
>> 2);
1225 if (channel2
> channel
) channel2
= 0;
1228 channel
= (unsigned char) (tg
- (gsign
* (*(xt
++) + *(yt
+ 1))));
1229 channel2
= (channel
>> 1) + (channel
>> 2);
1230 if (channel2
> channel
) channel2
= 0;
1233 channel
= (unsigned char) (tb
- (bsign
* (*(xt
++) + *(yt
+ 2))));
1234 channel2
= (channel
>> 1) + (channel
>> 2);
1235 if (channel2
> channel
) channel2
= 0;
1238 channel
= (unsigned char) (tr
- (rsign
* (*(xt
++) + *(yt
))));
1239 channel2
= channel
+ (channel
>> 3);
1240 if (channel2
< channel
) channel2
= ~0;
1243 channel
= (unsigned char) (tg
- (gsign
* (*(xt
++) + *(yt
+ 1))));
1244 channel2
= channel
+ (channel
>> 3);
1245 if (channel2
< channel
) channel2
= ~0;
1248 channel
= (unsigned char) (tb
- (bsign
* (*(xt
++) + *(yt
+ 2))));
1249 channel2
= channel
+ (channel
>> 3);
1250 if (channel2
< channel
) channel2
= ~0;
1259 void BImage::rgradient(void) {
1260 // rectangle gradient - based on original dgradient, written by
1261 // Mosfet (mosfet@kde.org)
1262 // adapted from kde sources for Blackbox by Brad Hughes
1264 float drx
, dgx
, dbx
, dry
, dgy
, dby
, xr
, xg
, xb
, yr
, yg
, yb
;
1265 int rsign
, gsign
, bsign
;
1266 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1267 unsigned int tr
= to
.red(), tg
= to
.green(), tb
= to
.blue(),
1268 *xt
= xtable
, *yt
= ytable
;
1270 register unsigned int x
, y
;
1272 dry
= drx
= (float) (to
.red() - from
.red());
1273 dgy
= dgx
= (float) (to
.green() - from
.green());
1274 dby
= dbx
= (float) (to
.blue() - from
.blue());
1276 rsign
= (drx
< 0) ? -2 : 2;
1277 gsign
= (dgx
< 0) ? -2 : 2;
1278 bsign
= (dbx
< 0) ? -2 : 2;
1280 xr
= yr
= (drx
/ 2);
1281 xg
= yg
= (dgx
/ 2);
1282 xb
= yb
= (dbx
/ 2);
1289 for (x
= 0; x
< width
; x
++) {
1290 *(xt
++) = (unsigned char) ((xr
< 0) ? -xr
: xr
);
1291 *(xt
++) = (unsigned char) ((xg
< 0) ? -xg
: xg
);
1292 *(xt
++) = (unsigned char) ((xb
< 0) ? -xb
: xb
);
1304 for (y
= 0; y
< height
; y
++) {
1305 *(yt
++) = ((unsigned char) ((yr
< 0) ? -yr
: yr
));
1306 *(yt
++) = ((unsigned char) ((yg
< 0) ? -yg
: yg
));
1307 *(yt
++) = ((unsigned char) ((yb
< 0) ? -yb
: yb
));
1314 // Combine tables to create gradient
1318 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1319 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1320 *(pr
++) = (unsigned char) (tr
- (rsign
* max(*(xt
++), *(yt
))));
1321 *(pg
++) = (unsigned char) (tg
- (gsign
* max(*(xt
++), *(yt
+ 1))));
1322 *(pb
++) = (unsigned char) (tb
- (bsign
* max(*(xt
++), *(yt
+ 2))));
1326 // faked interlacing effect
1327 unsigned char channel
, channel2
;
1329 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1330 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1332 channel
= (unsigned char) (tr
- (rsign
* max(*(xt
++), *(yt
))));
1333 channel2
= (channel
>> 1) + (channel
>> 2);
1334 if (channel2
> channel
) channel2
= 0;
1337 channel
= (unsigned char) (tg
- (gsign
* max(*(xt
++), *(yt
+ 1))));
1338 channel2
= (channel
>> 1) + (channel
>> 2);
1339 if (channel2
> channel
) channel2
= 0;
1342 channel
= (unsigned char) (tb
- (bsign
* max(*(xt
++), *(yt
+ 2))));
1343 channel2
= (channel
>> 1) + (channel
>> 2);
1344 if (channel2
> channel
) channel2
= 0;
1347 channel
= (unsigned char) (tr
- (rsign
* max(*(xt
++), *(yt
))));
1348 channel2
= channel
+ (channel
>> 3);
1349 if (channel2
< channel
) channel2
= ~0;
1352 channel
= (unsigned char) (tg
- (gsign
* max(*(xt
++), *(yt
+ 1))));
1353 channel2
= channel
+ (channel
>> 3);
1354 if (channel2
< channel
) channel2
= ~0;
1357 channel
= (unsigned char) (tb
- (bsign
* max(*(xt
++), *(yt
+ 2))));
1358 channel2
= channel
+ (channel
>> 3);
1359 if (channel2
< channel
) channel2
= ~0;
1368 void BImage::egradient(void) {
1369 // elliptic gradient - based on original dgradient, written by
1370 // Mosfet (mosfet@kde.org)
1371 // adapted from kde sources for Blackbox by Brad Hughes
1373 float drx
, dgx
, dbx
, dry
, dgy
, dby
, yr
, yg
, yb
, xr
, xg
, xb
;
1374 int rsign
, gsign
, bsign
;
1375 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1376 unsigned int *xt
= xtable
, *yt
= ytable
,
1377 tr
= (unsigned long) to
.red(),
1378 tg
= (unsigned long) to
.green(),
1379 tb
= (unsigned long) to
.blue();
1381 register unsigned int x
, y
;
1383 dry
= drx
= (float) (to
.red() - from
.red());
1384 dgy
= dgx
= (float) (to
.green() - from
.green());
1385 dby
= dbx
= (float) (to
.blue() - from
.blue());
1387 rsign
= (drx
< 0) ? -1 : 1;
1388 gsign
= (dgx
< 0) ? -1 : 1;
1389 bsign
= (dbx
< 0) ? -1 : 1;
1391 xr
= yr
= (drx
/ 2);
1392 xg
= yg
= (dgx
/ 2);
1393 xb
= yb
= (dbx
/ 2);
1400 for (x
= 0; x
< width
; x
++) {
1401 *(xt
++) = (unsigned long) (xr
* xr
);
1402 *(xt
++) = (unsigned long) (xg
* xg
);
1403 *(xt
++) = (unsigned long) (xb
* xb
);
1415 for (y
= 0; y
< height
; y
++) {
1416 *(yt
++) = (unsigned long) (yr
* yr
);
1417 *(yt
++) = (unsigned long) (yg
* yg
);
1418 *(yt
++) = (unsigned long) (yb
* yb
);
1425 // Combine tables to create gradient
1429 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1430 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1431 *(pr
++) = (unsigned char)
1432 (tr
- (rsign
* control
->getSqrt(*(xt
++) + *(yt
))));
1433 *(pg
++) = (unsigned char)
1434 (tg
- (gsign
* control
->getSqrt(*(xt
++) + *(yt
+ 1))));
1435 *(pb
++) = (unsigned char)
1436 (tb
- (bsign
* control
->getSqrt(*(xt
++) + *(yt
+ 2))));
1440 // faked interlacing effect
1441 unsigned char channel
, channel2
;
1443 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1444 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1446 channel
= (unsigned char)
1447 (tr
- (rsign
* control
->getSqrt(*(xt
++) + *(yt
))));
1448 channel2
= (channel
>> 1) + (channel
>> 2);
1449 if (channel2
> channel
) channel2
= 0;
1452 channel
= (unsigned char)
1453 (tg
- (gsign
* control
->getSqrt(*(xt
++) + *(yt
+ 1))));
1454 channel2
= (channel
>> 1) + (channel
>> 2);
1455 if (channel2
> channel
) channel2
= 0;
1458 channel
= (unsigned char)
1459 (tb
- (bsign
* control
->getSqrt(*(xt
++) + *(yt
+ 2))));
1460 channel2
= (channel
>> 1) + (channel
>> 2);
1461 if (channel2
> channel
) channel2
= 0;
1464 channel
= (unsigned char)
1465 (tr
- (rsign
* control
->getSqrt(*(xt
++) + *(yt
))));
1466 channel2
= channel
+ (channel
>> 3);
1467 if (channel2
< channel
) channel2
= ~0;
1470 channel
= (unsigned char)
1471 (tg
- (gsign
* control
->getSqrt(*(xt
++) + *(yt
+ 1))));
1472 channel2
= channel
+ (channel
>> 3);
1473 if (channel2
< channel
) channel2
= ~0;
1476 channel
= (unsigned char)
1477 (tb
- (bsign
* control
->getSqrt(*(xt
++) + *(yt
+ 2))));
1478 channel2
= channel
+ (channel
>> 3);
1479 if (channel2
< channel
) channel2
= ~0;
1488 void BImage::pcgradient(void) {
1489 // pipe cross gradient - based on original dgradient, written by
1490 // Mosfet (mosfet@kde.org)
1491 // adapted from kde sources for Blackbox by Brad Hughes
1493 float drx
, dgx
, dbx
, dry
, dgy
, dby
, xr
, xg
, xb
, yr
, yg
, yb
;
1494 int rsign
, gsign
, bsign
;
1495 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1496 unsigned int *xt
= xtable
, *yt
= ytable
,
1501 register unsigned int x
, y
;
1503 dry
= drx
= (float) (to
.red() - from
.red());
1504 dgy
= dgx
= (float) (to
.green() - from
.green());
1505 dby
= dbx
= (float) (to
.blue() - from
.blue());
1507 rsign
= (drx
< 0) ? -2 : 2;
1508 gsign
= (dgx
< 0) ? -2 : 2;
1509 bsign
= (dbx
< 0) ? -2 : 2;
1511 xr
= yr
= (drx
/ 2);
1512 xg
= yg
= (dgx
/ 2);
1513 xb
= yb
= (dbx
/ 2);
1520 for (x
= 0; x
< width
; x
++) {
1521 *(xt
++) = (unsigned char) ((xr
< 0) ? -xr
: xr
);
1522 *(xt
++) = (unsigned char) ((xg
< 0) ? -xg
: xg
);
1523 *(xt
++) = (unsigned char) ((xb
< 0) ? -xb
: xb
);
1535 for (y
= 0; y
< height
; y
++) {
1536 *(yt
++) = ((unsigned char) ((yr
< 0) ? -yr
: yr
));
1537 *(yt
++) = ((unsigned char) ((yg
< 0) ? -yg
: yg
));
1538 *(yt
++) = ((unsigned char) ((yb
< 0) ? -yb
: yb
));
1545 // Combine tables to create gradient
1548 // normal pcgradient
1549 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1550 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1551 *(pr
++) = (unsigned char) (tr
- (rsign
* min(*(xt
++), *(yt
))));
1552 *(pg
++) = (unsigned char) (tg
- (gsign
* min(*(xt
++), *(yt
+ 1))));
1553 *(pb
++) = (unsigned char) (tb
- (bsign
* min(*(xt
++), *(yt
+ 2))));
1557 // faked interlacing effect
1558 unsigned char channel
, channel2
;
1560 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1561 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1563 channel
= (unsigned char) (tr
- (rsign
* min(*(xt
++), *(yt
))));
1564 channel2
= (channel
>> 1) + (channel
>> 2);
1565 if (channel2
> channel
) channel2
= 0;
1568 channel
= (unsigned char) (tg
- (bsign
* min(*(xt
++), *(yt
+ 1))));
1569 channel2
= (channel
>> 1) + (channel
>> 2);
1570 if (channel2
> channel
) channel2
= 0;
1573 channel
= (unsigned char) (tb
- (gsign
* min(*(xt
++), *(yt
+ 2))));
1574 channel2
= (channel
>> 1) + (channel
>> 2);
1575 if (channel2
> channel
) channel2
= 0;
1578 channel
= (unsigned char) (tr
- (rsign
* min(*(xt
++), *(yt
))));
1579 channel2
= channel
+ (channel
>> 3);
1580 if (channel2
< channel
) channel2
= ~0;
1583 channel
= (unsigned char) (tg
- (gsign
* min(*(xt
++), *(yt
+ 1))));
1584 channel2
= channel
+ (channel
>> 3);
1585 if (channel2
< channel
) channel2
= ~0;
1588 channel
= (unsigned char) (tb
- (bsign
* min(*(xt
++), *(yt
+ 2))));
1589 channel2
= channel
+ (channel
>> 3);
1590 if (channel2
< channel
) channel2
= ~0;
1599 void BImage::cdgradient(void) {
1600 // cross diagonal gradient - based on original dgradient, written by
1601 // Mosfet (mosfet@kde.org)
1602 // adapted from kde sources for Blackbox by Brad Hughes
1604 float drx
, dgx
, dbx
, dry
, dgy
, dby
, yr
= 0.0, yg
= 0.0, yb
= 0.0,
1605 xr
= (float) from
.red(),
1606 xg
= (float) from
.green(),
1607 xb
= (float) from
.blue();
1608 unsigned char *pr
= red
, *pg
= green
, *pb
= blue
;
1609 unsigned int w
= width
* 2, h
= height
* 2, *xt
, *yt
;
1611 register unsigned int x
, y
;
1613 dry
= drx
= (float) (to
.red() - from
.red());
1614 dgy
= dgx
= (float) (to
.green() - from
.green());
1615 dby
= dbx
= (float) (to
.blue() - from
.blue());
1622 for (xt
= (xtable
+ (width
* 3) - 1), x
= 0; x
< width
; x
++) {
1623 *(xt
--) = (unsigned char) xb
;
1624 *(xt
--) = (unsigned char) xg
;
1625 *(xt
--) = (unsigned char) xr
;
1637 for (yt
= ytable
, y
= 0; y
< height
; y
++) {
1638 *(yt
++) = (unsigned char) yr
;
1639 *(yt
++) = (unsigned char) yg
;
1640 *(yt
++) = (unsigned char) yb
;
1647 // Combine tables to create gradient
1650 // normal cdgradient
1651 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1652 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1653 *(pr
++) = *(xt
++) + *(yt
);
1654 *(pg
++) = *(xt
++) + *(yt
+ 1);
1655 *(pb
++) = *(xt
++) + *(yt
+ 2);
1659 // faked interlacing effect
1660 unsigned char channel
, channel2
;
1662 for (yt
= ytable
, y
= 0; y
< height
; y
++, yt
+= 3) {
1663 for (xt
= xtable
, x
= 0; x
< width
; x
++) {
1665 channel
= *(xt
++) + *(yt
);
1666 channel2
= (channel
>> 1) + (channel
>> 2);
1667 if (channel2
> channel
) channel2
= 0;
1670 channel
= *(xt
++) + *(yt
+ 1);
1671 channel2
= (channel
>> 1) + (channel
>> 2);
1672 if (channel2
> channel
) channel2
= 0;
1675 channel
= *(xt
++) + *(yt
+ 2);
1676 channel2
= (channel
>> 1) + (channel
>> 2);
1677 if (channel2
> channel
) channel2
= 0;
1680 channel
= *(xt
++) + *(yt
);
1681 channel2
= channel
+ (channel
>> 3);
1682 if (channel2
< channel
) channel2
= ~0;
1685 channel
= *(xt
++) + *(yt
+ 1);
1686 channel2
= channel
+ (channel
>> 3);
1687 if (channel2
< channel
) channel2
= ~0;
1690 channel
= *(xt
++) + *(yt
+ 2);
1691 channel2
= channel
+ (channel
>> 3);
1692 if (channel2
< channel
) channel2
= ~0;
This page took 0.113215 seconds and 5 git commands to generate.