1 #include <lib/gdi/gpixmap.h>
9 gLookup::gLookup(int size
, const gPalette
&pal
, const gRGB
&start
, const gRGB
&end
)
12 build(size
, pal
, start
, end
);
15 void gLookup::build(int _size
, const gPalette
&pal
, const gRGB
&start
, const gRGB
&end
)
26 lookup
=new gColor
[size
];
28 for (int i
=0; i
<size
; i
++)
33 int rdiff
=-start
.r
+end
.r
;
34 int gdiff
=-start
.g
+end
.g
;
35 int bdiff
=-start
.b
+end
.b
;
36 int adiff
=-start
.a
+end
.a
;
37 rdiff
*=i
; rdiff
/=(size
-1);
38 gdiff
*=i
; gdiff
/=(size
-1);
39 bdiff
*=i
; bdiff
/=(size
-1);
40 adiff
*=i
; adiff
/=(size
-1);
47 lookup
[i
]=pal
.findColor(col
);
51 gPixmap
*gPixmap::lock()
57 void gPixmap::unlock()
59 contentlock
.unlock(1);
62 void gPixmap::fill(const eRect
&area
, const gColor
&color
)
64 if ((area
.height()<=0) || (area
.width()<=0))
67 for (int y
=area
.top(); y
<area
.bottom(); y
++)
68 memset(((__u8
*)data
)+y
*stride
+area
.left(), color
.color
, area
.width());
70 for (int y
=area
.top(); y
<area
.bottom(); y
++)
72 __u32
*dst
=(__u32
*)(((__u8
*)data
)+y
*stride
+area
.left()*bypp
);
76 if (clut
.data
&& color
< clut
.colors
)
77 col
=(clut
.data
[color
].a
<<24)|(clut
.data
[color
].r
<<16)|(clut
.data
[color
].g
<<8)|(clut
.data
[color
].b
);
85 eWarning("couldn't fill %d bpp", bpp
);
88 void gPixmap::blit(const gPixmap
&src
, ePoint pos
, const eRect
&clip
, int flag
)
90 eRect area
=eRect(pos
, src
.getSize());
92 area
&=eRect(ePoint(0, 0), getSize());
93 if ((area
.width()<0) || (area
.height()<0))
97 srcarea
.moveBy(-pos
.x(), -pos
.y());
99 __u8
*srcdata
=src
.uncompressdatanoreplace();
100 __u8
*srcptr
=srcdata
;
101 __u8
*dstptr
=(__u8
*)data
;
103 if ((bpp
== 8) && (src
.bpp
==8))
106 srcptr
+=srcarea
.left()*bypp
+srcarea
.top()*src
.stride
;
107 dstptr
+=area
.left()*bypp
+area
.top()*stride
;
108 for (int y
=0; y
<area
.height(); y
++)
110 if (flag
& blitAlphaTest
)
112 // no real alphatest yet
113 int width
=area
.width();
114 unsigned char *src
=(unsigned char*)srcptr
;
115 unsigned char *dst
=(unsigned char*)dstptr
;
116 // use duff's device here!
127 memcpy(dstptr
, srcptr
, area
.width()*bypp
);
131 } else if ((bpp
== 32) && (src
.bpp
==8))
135 for (int i
=0; i
<256; ++i
)
137 if (src
.clut
.data
&& (i
<src
.clut
.colors
))
138 pal
[i
]=(src
.clut
.data
[i
].a
<<24)|(src
.clut
.data
[i
].r
<<16)|(src
.clut
.data
[i
].g
<<8)|(src
.clut
.data
[i
].b
);
144 srcptr
+=srcarea
.left()*bypp
+srcarea
.top()*src
.stride
;
145 dstptr
+=area
.left()*bypp
+area
.top()*stride
;
146 for (int y
=0; y
<area
.height(); y
++)
148 if (flag
& blitAlphaTest
)
150 // no real alphatest yet
151 int width
=area
.width();
152 unsigned char *src
=(unsigned char*)srcptr
;
153 __u32
*dst
=(__u32
*)dstptr
;
154 // use duff's device here!
166 int width
=area
.width();
167 unsigned char *src
=(unsigned char*)srcptr
;
168 __u32
*dst
=(__u32
*)dstptr
;
176 eFatal("cannot blit %dbpp from %dbpp", bpp
, src
.bpp
);
177 if (src
.compressedsize
)
181 void gPixmap::mergePalette(const gPixmap
&target
)
183 if ((!clut
.colors
) || (!target
.clut
.colors
))
185 gColor
*lookup
=new gColor
[clut
.colors
];
187 for (int i
=0; i
<clut
.colors
; i
++)
188 lookup
[i
].color
=target
.clut
.findColor(clut
.data
[i
]);
191 clut
.colors
=target
.clut
.colors
;
192 clut
.data
=new gRGB
[clut
.colors
];
193 memcpy(clut
.data
, target
.clut
.data
, sizeof(gRGB
)*clut
.colors
);
195 __u8
*dstptr
=(__u8
*)data
;
197 for (int ay
=0; ay
<y
; ay
++)
199 for (int ax
=0; ax
<x
; ax
++)
200 dstptr
[ax
]=lookup
[dstptr
[ax
]];
207 void gPixmap::compressdata()
209 if (cancompress
&& !compressedsize
)
211 uLongf comprlen
= x
*y
*bypp
;
212 if (comprlen
> 1000) // only compress "big" images
215 __u8 compressed
[comprlen
];
216 if (compress2(compressed
,&comprlen
,(__u8
*)data
,comprlen
,Z_BEST_SPEED
) == Z_OK
)
218 delete[] (char*)data
;
219 data
= new __u8
[comprlen
];
220 memcpy(data
,compressed
,comprlen
);
221 compressedsize
=comprlen
;
227 void gPixmap::uncompressdata()
232 uLongf uncomprlen
= x
*y
*bypp
;
233 __u8
* uncompressed
= new __u8
[uncomprlen
];
234 uncompress(uncompressed
,&uncomprlen
,(__u8
*)data
,compressedsize
);
235 delete[] (char*)data
;
241 __u8
* gPixmap::uncompressdatanoreplace() const
245 uLongf uncomprlen
= x
*y
*bypp
;
246 __u8
* uncompressed
= new __u8
[uncomprlen
];
247 uncompress(uncompressed
,&uncomprlen
,(__u8
*)data
,compressedsize
);
253 void gPixmap::line(ePoint start
, ePoint dst
, gColor color
)
255 int Ax
=start
.x(), // dieser code rult ganz ganz doll weil er ganz ganz fast ist und auch sehr gut dokumentiert is
256 Ay
=start
.y(), Bx
=dst
.x(), // t. es handelt sich immerhin um den weltbekannten bresenham algorithmus der nicht nur
257 By
=dst
.y(); int dX
, dY
, fbXincr
, // sehr schnell ist sondern auch sehr gut dokumentiert und getestet wurde. nicht
258 fbYincr
, fbXYincr
, dPr
, dPru
, P
; __u8
// nur auf dem LCD der dbox, sondern auch ueberall anders. und auch auf der
259 *AfbAddr
= &((__u8
*)data
)[Ay
*stride
+Ax
*bypp
]; __u8
// dbox mit LCD soll das teil nun tun, und ich denke das tut es. ausse
260 *BfbAddr
= &((__u8
*)data
)[By
*stride
+Bx
*bypp
]; fbXincr
= // rdem hat dieser algo den vorteil dass man fehler sehr leicht fi
261 bypp
; if ( (dX
=Bx
-Ax
) >= 0) goto AFTERNEGX
; dX
=-dX
; // ndet und beheben kann. das liegt nicht zuletzt an den komment
262 fbXincr
=-1; AFTERNEGX
: fbYincr
=stride
; if ( (dY
=By
// aren. und ausserdem, je kuerzer der code, desto weniger k
263 -Ay
) >= 0) goto AFTERNEGY
; fbYincr
=-stride
; dY
=-dY
;AFTERNEGY
: // ann daran falsch sein. erwaehnte ich schon, da
264 fbXYincr
= fbXincr
+fbYincr
; if (dY
> dX
) goto YisIndependent
; dPr
= dY
+ // s dieser tolle code wahnsinnig schnell
265 dY
; P
= -dX
; dPru
= P
+P
; dY
= dX
>>1; XLOOP
: *AfbAddr
=color
; *BfbAddr
=color
; if ((P
+=dPr
) > 0) // ist? bye, tmbinc
266 goto RightAndUp
; AfbAddr
+=fbXincr
; BfbAddr
-=fbXincr
; if ((dY
=dY
-1) > 0) goto XLOOP
; *AfbAddr
=color
; if ((dX
& 1)
267 == 0) return; *BfbAddr
=color
; return; RightAndUp
: AfbAddr
+=fbXYincr
; BfbAddr
-=fbXYincr
; P
+=dPru
; if ((dY
=dY
-1) >
268 0) goto XLOOP
; *AfbAddr
=color
; if ((dX
& 1) == 0) return; *BfbAddr
=color
; return; YisIndependent
: dPr
= dX
+dX
; P
269 = -dY
; dPru
= P
+P
; dX
= dY
>>1; YLOOP
: *AfbAddr
=color
; *BfbAddr
=color
; if ((P
+=dPr
) > 0) goto RightAndUp2
; AfbAddr
270 +=fbYincr
; BfbAddr
-=fbYincr
; if ((dX
=dX
-1) > 0) goto YLOOP
; *AfbAddr
=color
; if ((dY
& 1) == 0) return; *BfbAddr
=
271 color
;return; RightAndUp2
: AfbAddr
+=fbXYincr
; BfbAddr
-=fbXYincr
; P
+=dPru
; if ((dX
=dX
-1) > 0) goto YLOOP
; *AfbAddr
272 =color
; if((dY
& 1) == 0) return; *BfbAddr
=color
; return; // nun ist der tolle code leider zu ende. tut mir leid.
275 gColor
gPalette::findColor(const gRGB
&rgb
) const
277 int difference
=1<<30, best_choice
=0;
278 for (int t
=0; t
<colors
; t
++)
281 int td
=(signed)(rgb
.r
-data
[t
].r
); td
*=td
; td
*=(255-data
[t
].a
);
285 td
=(signed)(rgb
.g
-data
[t
].g
); td
*=td
; td
*=(255-data
[t
].a
);
289 td
=(signed)(rgb
.b
-data
[t
].b
); td
*=td
; td
*=(255-data
[t
].a
);
293 td
=(signed)(rgb
.a
-data
[t
].a
); td
*=td
; td
*=255;
303 void gPixmap::finalLock()
311 :final(0),cancompress(false),compressedsize(0)
321 gImage::gImage(eSize size
, int _bpp
)
335 case 24: // never use 24bit mode
345 data
=new char[x
*y
*bypp
];
352 delete[] (char*)data
;