Merge branch 'master' of http://www-dev.cockos.com/wdl/WDL into updatewdl
[wdl/wdl-ol.git] / WDL / lice / lice.cpp
blobd1694df5ae3d4f83c74e5fe29dfed7c06c910829
1 /*
2 Cockos WDL - LICE - Lightweight Image Compositing Engine
3 Copyright (C) 2007 and later, Cockos Incorporated
4 File: lice.cpp (LICE core processing)
5 See lice.h for license and other information
6 */
9 #ifndef __LICE_CPP_IMPLEMENTED__
10 #define __LICE_CPP_IMPLEMENTED__
12 #include "lice.h"
13 #include <math.h>
14 #include <stdio.h> // only included in case we need to debug with sprintf etc
16 #include "lice_combine.h"
17 #include "lice_extended.h"
19 #ifndef _WIN32
20 #include "../swell/swell.h"
21 #endif
23 _LICE_ImageLoader_rec *LICE_ImageLoader_list;
25 LICE_pixel LICE_CombinePixels(LICE_pixel dest, LICE_pixel src, float alpha, int mode)
27 int r = LICE_GETR(src);
28 int g = LICE_GETG(src);
29 int b = LICE_GETB(src);
30 int a = LICE_GETA(src);
31 int al = (int)(alpha*256.0f);
33 #define __LICE__ACTION(COMBFUNC) COMBFUNC::doPix((LICE_pixel_chan*)&dest,r, g, b, a, al)
34 __LICE_ACTION_SRCALPHA(mode, al,false);
35 #undef __LICE__ACTION
37 return dest;
41 void LICE_CombinePixels2(LICE_pixel *destptr, int r, int g, int b, int a, int ia, int mode)
43 #define __LICE__ACTION(COMBFUNC) COMBFUNC::doPix((LICE_pixel_chan*)destptr,r, g, b, a, ia)
44 __LICE_ACTION_SRCALPHA(mode, ia, false);
45 #undef __LICE__ACTION
47 void LICE_CombinePixels2Clamp(LICE_pixel *destptr, int r, int g, int b, int a, int ia, int mode)
49 #define __LICE__ACTION(COMBFUNC) COMBFUNC::doPix((LICE_pixel_chan*)destptr,r, g, b, a, ia)
50 __LICE_ACTION_SRCALPHA(mode, ia, true);
51 #undef __LICE__ACTION
55 LICE_MemBitmap::LICE_MemBitmap(int w, int h, unsigned int linealign)
57 m_allocsize=0;
58 m_fb=0;
59 m_width=0;
60 m_height=0;
61 m_linealign = linealign > 1 ? ((linealign & ~(linealign-1))-1) : 0; // force to be contiguous bits
62 if (m_linealign>16) m_linealign=16;
63 if (w>0&&h>0) resize(w,h);
66 LICE_MemBitmap::~LICE_MemBitmap() { free(m_fb); }
68 bool LICE_MemBitmap::resize(int w, int h)
70 if (w!=m_width||h!=m_height)
72 #ifdef DEBUG_TIGHT_ALLOC // dont enable for anything you want to be even remotely fast
73 free(m_fb);
74 m_fb = (LICE_pixel *)malloc((m_allocsize = ((w+m_linealign)&~m_linealign)*h*sizeof(LICE_pixel)) + LICE_MEMBITMAP_ALIGNAMT);
75 m_width=m_fb?w:0;
76 m_height=m_fb?h:0;
77 return true;
78 #endif
79 int sz=(((m_width=w)+m_linealign)&~m_linealign)*(m_height=h)*sizeof(LICE_pixel);
81 if (sz<=0||w<1||h<1) { free(m_fb); m_fb=0; m_allocsize=0; }
82 else if (!m_fb) m_fb=(LICE_pixel*)malloc((m_allocsize=sz) + LICE_MEMBITMAP_ALIGNAMT);
83 else
85 if (sz>m_allocsize)
87 void *op=m_fb;
88 if (!(m_fb=(LICE_pixel*)realloc(m_fb,(m_allocsize=sz+sz/4)+LICE_MEMBITMAP_ALIGNAMT)))
90 free(op);
91 m_fb=(LICE_pixel*)malloc((m_allocsize=sz)+LICE_MEMBITMAP_ALIGNAMT);
95 if (!m_fb) {m_width=m_height=0; }
97 return true;
99 return false;
104 #ifndef _LICE_NO_SYSBITMAPS_
106 LICE_SysBitmap::LICE_SysBitmap(int w, int h)
108 m_allocw=m_alloch=0;
109 #ifdef _WIN32
110 m_dc = CreateCompatibleDC(NULL);
111 m_bitmap = 0;
112 m_oldbitmap = 0;
113 #else
114 m_dc=0;
115 #endif
116 m_bits=0;
117 m_width=m_height=0;
119 resize(w,h);
123 LICE_SysBitmap::~LICE_SysBitmap()
125 #ifdef _WIN32
126 if (m_oldbitmap && m_dc) SelectObject(m_dc,m_oldbitmap);
127 if (m_bitmap) DeleteObject(m_bitmap);
128 if (m_dc) DeleteDC(m_dc);
129 #else
130 if (m_dc)
131 SWELL_DeleteGfxContext(m_dc);
132 #endif
135 bool LICE_SysBitmap::resize(int w, int h)
137 #ifdef _WIN32
138 if (!m_dc) { m_width=m_height=0; m_bits=0; return false; }
139 #endif
141 if (m_width==w && m_height == h) return false;
143 m_width=w;
144 m_height=h;
146 #ifndef DEBUG_TIGHT_ALLOC
147 // dont resize down bitmaps
148 if (w && h && w <= m_allocw && h <= m_alloch && m_bits)
150 #ifndef _WIN32
151 if (isFlipped())
153 m_bits=(LICE_pixel*)SWELL_GetCtxFrameBuffer(m_dc);
154 m_bits += (m_alloch-h)*m_allocw;
156 #endif
157 return true;
159 #endif//!DEBUG_TIGHT_ALLOC
161 w = (w+3)&~3; // always keep backing store a multiple of 4px wide
164 m_allocw=w;
165 m_alloch=h;
167 #ifdef _WIN32
168 if (m_oldbitmap)
170 SelectObject(m_dc,m_oldbitmap);
171 m_oldbitmap=0;
173 if (m_bitmap) DeleteObject(m_bitmap);
174 m_bitmap=0;
175 m_bits=0;
178 if (w<1 || h<1) return false;
180 BITMAPINFO pbmInfo = {0,};
181 pbmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
182 pbmInfo.bmiHeader.biWidth = w;
183 pbmInfo.bmiHeader.biHeight = isFlipped()?h:-h;
184 pbmInfo.bmiHeader.biPlanes = 1;
185 pbmInfo.bmiHeader.biBitCount = sizeof(LICE_pixel)*8;
186 pbmInfo.bmiHeader.biCompression = BI_RGB;
187 m_bitmap = CreateDIBSection( NULL, &pbmInfo, DIB_RGB_COLORS, (void **)&m_bits, NULL, 0);
189 if (m_bitmap) m_oldbitmap=SelectObject(m_dc, m_bitmap);
190 else { m_width=m_height=0; m_bits=0; }
191 #else
192 if (m_dc) SWELL_DeleteGfxContext(m_dc);
193 m_dc=0;
194 m_bits=0;
196 if (w<1 || h<1) return false;
198 m_dc=SWELL_CreateMemContext(0,w,h);
199 if (!m_dc) { m_width=m_height=0; m_bits=0; }
200 else m_bits=(LICE_pixel*)SWELL_GetCtxFrameBuffer(m_dc);
201 #endif
203 return true;
206 #endif // _LICE_NO_SYSBITMAPS_
210 #ifndef LICE_NO_BLIT_SUPPORT
211 void LICE_Copy(LICE_IBitmap *dest, LICE_IBitmap *src) // resizes dest
213 if (src&&dest)
215 dest->resize(src->getWidth(),src->getHeight());
216 LICE_Blit(dest,src,0,0,NULL,1.0,LICE_BLIT_MODE_COPY);
219 #endif
221 template<class COMBFUNC> class _LICE_Template_Blit0 // these always templated
223 public:
224 static void solidBlitFAST(LICE_pixel *dest, int w, int h,
225 LICE_pixel color,
226 int dest_span)
228 while (h--)
230 LICE_pixel *pout=dest;
231 int n=w;
232 while (n--)
234 COMBFUNC::doPixFAST(pout,color);
235 ++pout;
237 dest+=dest_span;
243 static void scaleBlitFAST(LICE_pixel_chan *dest, const LICE_pixel_chan *src, int w, int h,
244 int icurx, int icury, int idx, int idy, unsigned int clipright, unsigned int clipbottom,
245 int src_span, int dest_span)
247 LICE_pixel* destpx = (LICE_pixel*) dest;
248 int destpxspan = dest_span*(int)sizeof(LICE_pixel_chan)/(int)sizeof(LICE_pixel);
250 while (h--)
252 const unsigned int cury = icury >> 16;
253 if (cury < clipbottom)
255 int curx=icurx;
256 const LICE_pixel_chan *inptr=src + cury * src_span;
257 LICE_pixel* pout = destpx;
258 int n=w;
259 while (n--)
261 const unsigned int offs=curx >> 16;
262 if (offs<clipright)
264 COMBFUNC::doPixFAST(pout,((LICE_pixel *)inptr)[offs]);
267 ++pout;
268 curx+=idx;
271 destpx += destpxspan;
272 icury+=idy;
278 #ifndef LICE_FAVOR_SIZE_EXTREME
279 template<class COMBFUNC>
280 #endif
281 class _LICE_Template_Blit1 // these controlled by LICE_FAVOR_SIZE_EXTREME
283 #ifdef LICE_FAVOR_SIZE_EXTREME
284 #define DOPIX(pout,r,g,b,a,ia) combFunc(pout,r,g,b,a,ia);
285 #else
286 #define DOPIX(pout,r,g,b,a,ia) COMBFUNC::doPix(pout,r,g,b,a,ia);
287 #endif
288 public:
289 static void solidBlit(LICE_pixel_chan *dest, int w, int h,
290 int ir, int ig, int ib, int ia,
291 int dest_span
292 #ifdef LICE_FAVOR_SIZE_EXTREME
293 , LICE_COMBINEFUNC combFunc
294 #endif
297 while (h--)
299 LICE_pixel_chan *pout=dest;
300 int n=w;
301 while (n--)
303 DOPIX(pout,ir,ig,ib,ia,ia);
304 pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan);
306 dest+=dest_span;
309 static void gradBlit(LICE_pixel_chan *dest, int w, int h,
310 int ir, int ig, int ib, int ia,
311 int drdx, int dgdx, int dbdx, int dadx,
312 int drdy, int dgdy, int dbdy, int dady,
313 int dest_span
314 #ifdef LICE_FAVOR_SIZE_EXTREME
315 , LICE_COMBINEFUNC combFunc
316 #endif
319 while (h--)
321 int r=ir,g=ig,b=ib,a=ia;
322 ir+=drdy; ig+=dgdy; ib+=dbdy; ia+=dady;
323 LICE_pixel_chan *pout=dest;
324 int n=w;
325 while (n--)
327 int ia=a/65536;
328 DOPIX(pout,r/65536,g/65536,b/65536,ia,ia);
329 pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan);
330 r+=drdx; g+=dgdx; b+=dbdx; a+=dadx;
332 dest+=dest_span;
336 #undef DOPIX
340 #ifndef LICE_FAVOR_SIZE
341 template<class COMBFUNC>
342 #endif
343 class _LICE_Template_Blit2 // these controlled by LICE_FAVOR_SIZE
345 #ifdef LICE_FAVOR_SIZE
346 #define DOPIX(pout,r,g,b,a,ia) combFunc(pout,r,g,b,a,ia);
347 #else
348 #define DOPIX(pout,r,g,b,a,ia) COMBFUNC::doPix(pout,r,g,b,a,ia);
349 #endif
351 public:
353 static void blit(LICE_pixel_chan *dest, const LICE_pixel_chan *src, int w, int h, int src_span, int dest_span, int ia
354 #ifdef LICE_FAVOR_SIZE
355 , LICE_COMBINEFUNC combFunc
356 #endif
359 while (h-->0)
361 int n=w;
362 const LICE_pixel_chan *pin=src;
363 LICE_pixel_chan *pout=dest;
364 while (n--)
367 DOPIX(pout,pin[LICE_PIXEL_R],pin[LICE_PIXEL_G],pin[LICE_PIXEL_B],pin[LICE_PIXEL_A],ia);
369 pin += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan);
370 pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan);
372 dest+=dest_span;
373 src += src_span;
377 // this is only designed for filtering down an image approx 2:1 to 4:1 or so.. it'll work (poortly) for higher, and for less it's crap too.
378 // probably need to redo it using linear interpolation of the filter coefficients, but bleh I'm gonna go play some call of duty
379 static void scaleBlitFilterDown(LICE_pixel_chan *dest, const LICE_pixel_chan *src, int w, int h,
380 int icurx, int icury, int idx, int idy, int clipright, int clipbottom,
381 int src_span, int dest_span, int ia, const int *filter, int filt_start, int filtsz
382 #ifdef LICE_FAVOR_SIZE
383 , LICE_COMBINEFUNC combFunc
384 #endif
389 while (h--)
391 int cury = icury >> 16;
392 int curx=icurx;
393 int n=w;
394 if (cury >= 0 && cury < clipbottom)
396 const LICE_pixel_chan *inptr=src + (cury+filt_start) * src_span;
397 LICE_pixel_chan *pout=dest;
398 while (n--)
400 int offs=curx >> 16;
401 if (offs>=0 && offs<clipright)
403 int r=0,g=0,b=0,a=0;
404 int sc=0;
405 int fy=filtsz;
406 int ypos=cury+filt_start;
407 const LICE_pixel_chan *rdptr = inptr + (offs + filt_start)*(int) (sizeof(LICE_pixel)/sizeof(LICE_pixel_chan));
408 const int *scaletab = filter;
409 while (fy--)
411 if (ypos >= clipbottom) break;
413 if (ypos >= 0)
415 int xpos=offs + filt_start;
416 const LICE_pixel_chan *pin = rdptr;
417 int fx=filtsz;
418 while (fx--)
420 int tsc = *scaletab++;
421 if (xpos >= 0 && xpos < clipright)
423 r+=pin[LICE_PIXEL_R]*tsc;
424 g+=pin[LICE_PIXEL_G]*tsc;
425 b+=pin[LICE_PIXEL_B]*tsc;
426 a+=pin[LICE_PIXEL_A]*tsc;
427 sc+=tsc;
429 xpos++;
430 pin+=sizeof(LICE_pixel)/sizeof(LICE_pixel_chan);
433 else scaletab += filtsz;
435 ypos++;
436 rdptr+=src_span;
438 if (sc>0)
440 DOPIX(pout,r/sc,g/sc,b/sc,a/sc,ia);
444 pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan);
445 curx+=idx;
448 dest+=dest_span;
449 icury+=idy;
452 static void scaleBlit(LICE_pixel_chan *dest, const LICE_pixel_chan *src, int w, int h,
453 int icurx, int icury, int idx, int idy, unsigned int clipright, unsigned int clipbottom,
454 int src_span, int dest_span, int ia, int filtermode
455 #ifdef LICE_FAVOR_SIZE
456 , LICE_COMBINEFUNC combFunc
457 #endif
462 if (filtermode == LICE_BLIT_FILTER_BILINEAR)
464 while (h--)
466 const unsigned int cury = icury >> 16;
467 const int yfrac=icury&65535;
468 int curx=icurx;
469 const LICE_pixel_chan *inptr=src + cury * src_span;
470 LICE_pixel_chan *pout=dest;
471 int n=w;
472 if (cury < clipbottom-1)
474 while (n--)
476 const unsigned int offs=curx >> 16;
477 const LICE_pixel_chan *pin = inptr + offs*sizeof(LICE_pixel);
478 if (offs<clipright-1)
480 int r,g,b,a;
481 __LICE_BilinearFilterI(&r,&g,&b,&a,pin,pin+src_span,curx&0xffff,yfrac);
482 DOPIX(pout,r,g,b,a,ia)
484 else if (offs==clipright-1)
486 int r,g,b,a;
487 __LICE_LinearFilterI(&r,&g,&b,&a,pin,pin+src_span,yfrac);
488 DOPIX(pout,r,g,b,a,ia)
491 pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan);
492 curx+=idx;
495 else if (cury == clipbottom-1)
497 while (n--)
499 const unsigned int offs=curx >> 16;
500 const LICE_pixel_chan *pin = inptr + offs*sizeof(LICE_pixel);
501 if (offs<clipright-1)
503 int r,g,b,a;
504 __LICE_LinearFilterI(&r,&g,&b,&a,pin,pin+sizeof(LICE_pixel)/sizeof(LICE_pixel_chan),curx&0xffff);
505 DOPIX(pout,r,g,b,a,ia)
507 else if (offs==clipright-1)
509 DOPIX(pout,pin[LICE_PIXEL_R],pin[LICE_PIXEL_G],pin[LICE_PIXEL_B],pin[LICE_PIXEL_A],ia)
512 pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan);
513 curx+=idx;
516 dest+=dest_span;
517 icury+=idy;
520 else
522 while (h--)
524 const unsigned int cury = icury >> 16;
525 if (cury < clipbottom)
527 int curx=icurx;
528 const LICE_pixel_chan *inptr=src + cury * src_span;
529 LICE_pixel_chan *pout=dest;
530 int n=w;
531 while (n--)
533 const unsigned int offs=curx >> 16;
534 if (offs<clipright)
536 const LICE_pixel_chan *pin = inptr + offs*sizeof(LICE_pixel);
538 DOPIX(pout,pin[LICE_PIXEL_R],pin[LICE_PIXEL_G],pin[LICE_PIXEL_B],pin[LICE_PIXEL_A],ia)
541 pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan);
542 curx+=idx;
545 dest+=dest_span;
546 icury+=idy;
552 #undef DOPIX
555 #ifdef LICE_FAVOR_SPEED
556 template<class COMBFUNC>
557 #endif
558 class _LICE_Template_Blit3 // stuff controlled by LICE_FAVOR_SPEED
560 #ifndef LICE_FAVOR_SPEED
561 #define DOPIX(pout,r,g,b,a,ia) combFunc(pout,r,g,b,a,ia);
562 #else
563 #define DOPIX(pout,r,g,b,a,ia) COMBFUNC::doPix(pout,r,g,b,a,ia);
564 #endif
566 public:
568 static void deltaBlit(LICE_pixel_chan *dest, const LICE_pixel_chan *src, int w, int h,
569 int isrcx, int isrcy, int idsdx, int idtdx, int idsdy, int idtdy,
570 int idsdxdy, int idtdxdy,
571 unsigned int src_right, unsigned int src_bottom,
572 int src_span, int dest_span, int ia, int filtermode
573 #ifndef LICE_FAVOR_SPEED
574 , LICE_COMBINEFUNC combFunc
575 #endif
578 if (filtermode == LICE_BLIT_FILTER_BILINEAR)
580 while (h--)
582 int thisx=isrcx;
583 int thisy=isrcy;
584 LICE_pixel_chan *pout=dest;
585 int n=w;
586 while (n--)
588 const unsigned int cury = thisy >> 16;
589 const unsigned int curx = thisx >> 16;
590 if (cury < src_bottom-1)
592 if (curx < src_right-1)
594 const LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel);
595 int r,g,b,a;
597 __LICE_BilinearFilterI(&r,&g,&b,&a,pin,pin+src_span,thisx&65535,thisy&65535);
599 DOPIX(pout,r,g,b,a,ia);
601 else if (curx==src_right-1)
604 const LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel);
605 int r,g,b,a;
607 __LICE_LinearFilterI(&r,&g,&b,&a,pin,pin+src_span,thisy&65535);
608 DOPIX(pout,r,g,b,a,ia);
611 else if (cury==src_bottom-1)
613 if (curx<src_right-1)
615 const LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel);
617 int r,g,b,a;
619 __LICE_LinearFilterI(&r,&g,&b,&a,pin,pin+sizeof(LICE_pixel)/sizeof(LICE_pixel_chan),thisx&65535);
621 DOPIX(pout,r,g,b,a,ia);
623 else if (curx==src_right-1)
625 const LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel);
626 DOPIX(pout,pin[LICE_PIXEL_R],pin[LICE_PIXEL_G],pin[LICE_PIXEL_B],pin[LICE_PIXEL_A],ia);
630 pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan);
631 thisx+=idsdx;
632 thisy+=idtdx;
634 idsdx+=idsdxdy;
635 idtdx+=idtdxdy;
636 isrcx+=idsdy;
637 isrcy+=idtdy;
638 dest+=dest_span;
641 else
643 while (h--)
645 int thisx=isrcx;
646 int thisy=isrcy;
647 LICE_pixel_chan *pout=dest;
648 int n=w;
649 while (n--)
651 const unsigned int cury = thisy >> 16;
652 const unsigned int curx = thisx >> 16;
653 if (cury < src_bottom && curx < src_right)
655 const LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel);
657 DOPIX(pout,pin[LICE_PIXEL_R],pin[LICE_PIXEL_G],pin[LICE_PIXEL_B],pin[LICE_PIXEL_A],ia);
660 pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan);
661 thisx+=idsdx;
662 thisy+=idtdx;
664 idsdx+=idsdxdy;
665 idtdx+=idtdxdy;
666 isrcx+=idsdy;
667 isrcy+=idtdy;
668 dest+=dest_span;
673 #undef DOPIX
676 #ifdef LICE_FAVOR_SPEED
677 template<class COMBFUNC>
678 #endif
679 class _LICE_Template_Blit4 // stuff controlled by LICE_FAVOR_SPEED
681 #ifndef LICE_FAVOR_SPEED
682 #define DOPIX(pout,r,g,b,a,ia) combFunc(pout,r,g,b,a,ia);
683 #else
684 #define DOPIX(pout,r,g,b,a,ia) COMBFUNC::doPix(pout,r,g,b,a,ia);
685 #endif
687 public:
689 static void deltaBlitAlpha(LICE_pixel_chan *dest, const LICE_pixel_chan *src, int w, int h,
690 int isrcx, int isrcy, int idsdx, int idtdx, int idsdy, int idtdy,
691 int idsdxdy, int idtdxdy,
692 unsigned int src_right, unsigned int src_bottom,
693 int src_span, int dest_span, int ia, int idadx, int idady, int idadxdy, int filtermode
694 #ifndef LICE_FAVOR_SPEED
695 , LICE_COMBINEFUNC combFunc
696 #endif
699 if (filtermode == LICE_BLIT_FILTER_BILINEAR)
701 while (h--)
703 int thisx=isrcx;
704 int thisy=isrcy;
705 int thisa=ia;
706 LICE_pixel_chan *pout=dest;
707 int n=w;
708 while (n--)
710 const unsigned int cury = thisy >> 16;
711 const unsigned int curx = thisx >> 16;
712 if (cury < src_bottom-1)
714 if (curx < src_right-1)
716 const LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel);
717 int r,g,b,a;
719 __LICE_BilinearFilterI(&r,&g,&b,&a,pin,pin+src_span,thisx&65535,thisy&65535);
721 DOPIX(pout,r,g,b,a,thisa>>8);
723 else if (curx==src_right-1)
726 const LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel);
727 int r,g,b,a;
729 __LICE_LinearFilterI(&r,&g,&b,&a,pin,pin+src_span,thisy&65535);
730 DOPIX(pout,r,g,b,a,thisa>>8);
733 else if (cury==src_bottom-1)
735 if (curx<src_right-1)
737 const LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel);
739 int r,g,b,a;
741 __LICE_LinearFilterI(&r,&g,&b,&a,pin,pin+sizeof(LICE_pixel)/sizeof(LICE_pixel_chan),thisx&65535);
743 DOPIX(pout,r,g,b,a,thisa>>8);
745 else if (curx==src_right-1)
747 const LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel);
748 DOPIX(pout,pin[LICE_PIXEL_R],pin[LICE_PIXEL_G],pin[LICE_PIXEL_B],pin[LICE_PIXEL_A],thisa>>8);
752 pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan);
753 thisx+=idsdx;
754 thisy+=idtdx;
755 thisa+=idadx;
757 idsdx+=idsdxdy;
758 idtdx+=idtdxdy;
759 idadx+=idadxdy;
760 isrcx+=idsdy;
761 isrcy+=idtdy;
762 ia += idady;
763 dest+=dest_span;
766 else
768 while (h--)
770 int thisx=isrcx;
771 int thisy=isrcy;
772 int thisa=ia;
773 LICE_pixel_chan *pout=dest;
774 int n=w;
775 while (n--)
777 const unsigned int cury = thisy >> 16;
778 const unsigned int curx = thisx >> 16;
779 if (cury < src_bottom && curx < src_right)
781 const LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel);
783 DOPIX(pout,pin[LICE_PIXEL_R],pin[LICE_PIXEL_G],pin[LICE_PIXEL_B],pin[LICE_PIXEL_A],thisa>>8);
786 pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan);
787 thisx+=idsdx;
788 thisy+=idtdx;
789 thisa+=idadx;
791 idsdx+=idsdxdy;
792 idtdx+=idtdxdy;
793 idadx+=idadxdy;
794 isrcx+=idsdy;
795 isrcy+=idtdy;
796 ia+=idady;
797 dest+=dest_span;
802 #undef DOPIX
807 #ifndef LICE_NO_GRADIENT_SUPPORT
809 void LICE_GradRect(LICE_IBitmap *dest, int dstx, int dsty, int dstw, int dsth,
810 float ir, float ig, float ib, float ia,
811 float drdx, float dgdx, float dbdx, float dadx,
812 float drdy, float dgdy, float dbdy, float dady,
813 int mode)
815 if (!dest) return;
817 ir*=255.0; ig*=255.0; ib*=255.0; ia*=256.0;
818 drdx*=255.0; dgdx*=255.0; dbdx*=255.0; dadx*=256.0;
819 drdy*=255.0; dgdy*=255.0; dbdy*=255.0; dady*=256.0;
820 // dont scale alpha
822 // clip to output
823 if (dstx < 0)
825 ir-=dstx*drdx; ig-=dstx*dgdx; ib-=dstx*dbdx; ia-=dstx*dadx;
826 dstw+=dstx;
827 dstx=0;
829 if (dsty < 0)
831 ir -= dsty*drdy; ig-=dsty*dgdy; ib -= dsty*dbdy; ia -= dsty*dady;
832 dsth += dsty;
833 dsty=0;
836 int dest_span=dest->getRowSpan()*sizeof(LICE_pixel);
837 LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits();
839 const int destbm_w = dest->getWidth(), destbm_h = dest->getHeight();
841 if (!pdest || !dest_span || dstw < 1 || dsth < 1 || dstx >= destbm_w || dsty >= destbm_h) return;
843 if (dstw > destbm_w-dstx) dstw = destbm_w-dstx;
844 if (dsth > destbm_h-dsty) dsth = destbm_h-dsty;
846 if (dest->isFlipped())
848 pdest += (destbm_h-dsty - 1)*dest_span;
849 dest_span=-dest_span;
851 else
853 pdest += dsty*dest_span;
855 pdest+=dstx*sizeof(LICE_pixel);
856 #define TOFIX(a) ((int)((a)*65536.0))
858 int iir=TOFIX(ir), iig=TOFIX(ig), iib=TOFIX(ib), iia=TOFIX(ia), idrdx=TOFIX(drdx),idgdx=TOFIX(dgdx),idbdx=TOFIX(dbdx),idadx=TOFIX(dadx),
859 idrdy=TOFIX(drdy), idgdy=TOFIX(dgdy), idbdy=TOFIX(dbdy), idady=TOFIX(dady);
862 #ifdef LICE_FAVOR_SIZE_EXTREME
863 LICE_COMBINEFUNC blitfunc=NULL;
864 #define __LICE__ACTION(comb) blitfunc=comb::doPix;
865 #else
867 #define __LICE__ACTION(comb) _LICE_Template_Blit1<comb>::gradBlit(pdest,dstw,dsth,iir,iig,iib,iia,idrdx,idgdx,idbdx,idadx,idrdy,idgdy,idbdy,idady,dest_span)
868 #endif
870 // todo: could predict whether or not the colors will ever go out of 0.255 range and optimize
872 if ((mode & LICE_BLIT_MODE_MASK)==LICE_BLIT_MODE_COPY && iia==65536 && idady==0 && idadx == 0)
874 __LICE__ACTION(_LICE_CombinePixelsClobberClamp);
876 else
878 __LICE_ACTION_NOSRCALPHA(mode,256,true);
880 #undef __LICE__ACTION
882 #ifdef LICE_FAVOR_SIZE_EXTREME
883 if (blitfunc) _LICE_Template_Blit1::gradBlit(pdest,dstw,dsth,iir,iig,iib,iia,idrdx,idgdx,idbdx,idadx,idrdy,idgdy,idbdy,idady,dest_span,blitfunc);
884 #endif
886 #undef TOFIX
889 #endif
892 #ifndef LICE_NO_BLIT_SUPPORT
893 void LICE_Blit(LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, int srcx, int srcy, int srcw, int srch, float alpha, int mode)
895 RECT r={srcx,srcy,srcx+srcw,srcy+srch};
896 LICE_Blit(dest,src,dstx,dsty,&r,alpha,mode);
899 void LICE_Blit(LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, const RECT *srcrect, float alpha, int mode)
901 if (!dest || !src || !alpha) return;
903 RECT sr={0,0,src->getWidth(),src->getHeight()};
904 if (srcrect)
906 sr=*srcrect;
907 if (sr.left < 0) { dstx-=sr.left; sr.left=0; }
908 if (sr.top < 0) { dsty-=sr.top; sr.top=0; }
909 if (sr.right > src->getWidth()) sr.right=src->getWidth();
910 if (sr.bottom > src->getHeight()) sr.bottom = src->getHeight();
913 // clip to output
914 if (dstx < 0) { sr.left -= dstx; dstx=0; }
915 if (dsty < 0) { sr.top -= dsty; dsty=0; }
917 const int destbm_w = dest->getWidth(), destbm_h = dest->getHeight();
918 if (sr.right <= sr.left || sr.bottom <= sr.top || dstx >= destbm_w || dsty >= destbm_h) return;
920 if (sr.right > sr.left + (destbm_w-dstx)) sr.right = sr.left + (destbm_w-dstx);
921 if (sr.bottom > sr.top + (destbm_h-dsty)) sr.bottom = sr.top + (destbm_h-dsty);
923 // ignore blits that are 0
924 if (sr.right <= sr.left || sr.bottom <= sr.top) return;
926 #ifndef DISABLE_LICE_EXTENSIONS
927 if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_BLIT_ACCEL))
929 LICE_Ext_Blit_acceldata data(src, dstx, dsty,
930 sr.left, sr.top,
931 sr.right-sr.left, sr.bottom-sr.top,
932 alpha, mode);
933 if (dest->Extended(LICE_EXT_BLIT_ACCEL, &data)) return;
935 #endif
938 int dest_span=dest->getRowSpan()*sizeof(LICE_pixel);
939 int src_span=src->getRowSpan()*sizeof(LICE_pixel);
940 const LICE_pixel_chan *psrc = (LICE_pixel_chan *)src->getBits();
941 LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits();
942 if (!psrc || !pdest) return;
944 if (src->isFlipped())
946 psrc += (src->getHeight()-sr.top - 1)*src_span;
947 src_span=-src_span;
949 else psrc += sr.top*src_span;
950 psrc += sr.left*sizeof(LICE_pixel);
952 if (dest->isFlipped())
954 pdest += (destbm_h-dsty - 1)*dest_span;
955 dest_span=-dest_span;
957 else pdest += dsty*dest_span;
958 pdest+=dstx*sizeof(LICE_pixel);
960 int i=sr.bottom-sr.top;
961 int cpsize=sr.right-sr.left;
963 if ((mode&LICE_BLIT_MODE_MASK) >= LICE_BLIT_MODE_CHANCOPY && (mode&LICE_BLIT_MODE_MASK) < LICE_BLIT_MODE_CHANCOPY+0x10)
965 while (i-->0)
967 LICE_pixel_chan *o=pdest+((mode>>2)&3);
968 const LICE_pixel_chan *in=psrc+(mode&3);
969 int a=cpsize;
970 while (a--)
972 *o=*in;
973 o+=sizeof(LICE_pixel);
974 in+=sizeof(LICE_pixel);
976 pdest+=dest_span;
977 psrc += src_span;
980 // special fast case for copy with no source alpha and alpha=1.0 or 0.5
981 else if ((mode&(LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA))==LICE_BLIT_MODE_COPY && (alpha==1.0||alpha==0.5))
983 if (alpha==0.5)
985 while (i-->0)
987 int a=cpsize;
988 const LICE_pixel *rd = (LICE_pixel *)psrc;
989 LICE_pixel *wr = (LICE_pixel *)pdest;
990 while (a-->0)
992 *wr = ((*wr>>1)&0x7f7f7f7f)+((*rd++>>1)&0x7f7f7f7f);
993 wr++;
996 pdest+=dest_span;
997 psrc += src_span;
1000 else
1002 while (i-->0)
1004 memcpy(pdest,psrc,cpsize*sizeof(LICE_pixel));
1005 pdest+=dest_span;
1006 psrc += src_span;
1010 else
1012 int ia=(int)(alpha*256.0);
1013 #ifdef LICE_FAVOR_SIZE
1014 LICE_COMBINEFUNC blitfunc=NULL;
1015 #define __LICE__ACTION(comb) blitfunc=comb::doPix;
1016 #else
1017 #define __LICE__ACTION(comb) _LICE_Template_Blit2<comb>::blit(pdest,psrc,cpsize,i,src_span,dest_span,ia)
1018 #endif
1020 __LICE_ACTION_SRCALPHA(mode,ia,false);
1022 #undef __LICE__ACTION
1024 #ifdef LICE_FAVOR_SIZE
1025 if (blitfunc) _LICE_Template_Blit2::blit(pdest,psrc,cpsize,i,src_span,dest_span,ia,blitfunc);
1026 #endif
1030 #endif
1032 #ifndef LICE_NO_BLUR_SUPPORT
1034 void LICE_Blur(LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, int srcx, int srcy, int srcw, int srch) // src and dest can overlap, however it may look fudgy if they do
1036 if (!dest || !src) return;
1038 RECT sr={srcx,srcy,srcx+srcw,srcy+srch};
1039 if (sr.left < 0) sr.left=0;
1040 if (sr.top < 0) sr.top=0;
1041 if (sr.right > src->getWidth()) sr.right=src->getWidth();
1042 if (sr.bottom > src->getHeight()) sr.bottom = src->getHeight();
1044 // clip to output
1045 if (dstx < 0) { sr.left -= dstx; dstx=0; }
1046 if (dsty < 0) { sr.top -= dsty; dsty=0; }
1048 const int destbm_w = dest->getWidth(), destbm_h = dest->getHeight();
1049 if (sr.right <= sr.left || sr.bottom <= sr.top || dstx >= destbm_w || dsty >= destbm_h) return;
1051 if (sr.right > sr.left + (destbm_w-dstx)) sr.right = sr.left + (destbm_w-dstx);
1052 if (sr.bottom > sr.top + (destbm_h-dsty)) sr.bottom = sr.top + (destbm_h-dsty);
1054 // ignore blits that are smaller than 2x2
1055 if (sr.right <= sr.left+1 || sr.bottom <= sr.top+1) return;
1057 int dest_span=dest->getRowSpan();
1058 int src_span=src->getRowSpan();
1059 const LICE_pixel *psrc = (LICE_pixel *)src->getBits();
1060 LICE_pixel *pdest = (LICE_pixel *)dest->getBits();
1061 if (!psrc || !pdest) return;
1063 if (src->isFlipped())
1065 psrc += (src->getHeight()-sr.top - 1)*src_span;
1066 src_span=-src_span;
1068 else psrc += sr.top*src_span;
1069 psrc += sr.left;
1071 if (dest->isFlipped())
1073 pdest += (destbm_h-dsty - 1)*dest_span;
1074 dest_span=-dest_span;
1076 else pdest += dsty*dest_span;
1077 pdest+=dstx;
1079 LICE_pixel *tmpbuf=NULL;
1080 int w=sr.right-sr.left;
1082 // buffer to save the last unprocessed lines for the cases where blurring from a bitmap to itself
1083 LICE_pixel turdbuf[2048];
1084 if (src==dest)
1086 if (w <= (int) (sizeof(turdbuf)/sizeof(turdbuf[0])/2)) tmpbuf=turdbuf;
1087 else tmpbuf=(LICE_pixel*)malloc(w*2*sizeof(LICE_pixel));
1090 int i;
1091 for (i = sr.top; i < sr.bottom; i ++)
1093 if (tmpbuf)
1094 memcpy(tmpbuf+((i&1)?w:0),psrc,w*sizeof(LICE_pixel));
1096 if (i==sr.top || i==sr.bottom-1)
1098 const LICE_pixel *psrc2=psrc+(i==sr.top ? src_span : -src_span);
1100 LICE_pixel lp;
1102 pdest[0] = LICE_PIXEL_HALF(lp=psrc[0]) +
1103 LICE_PIXEL_QUARTER(psrc[1]) +
1104 LICE_PIXEL_QUARTER(psrc2[0]);
1105 int x;
1106 for (x = 1; x < w-1; x ++)
1108 LICE_pixel tp;
1109 pdest[x] = LICE_PIXEL_HALF(tp=psrc[x]) +
1110 LICE_PIXEL_QUARTER(psrc2[x]) +
1111 LICE_PIXEL_EIGHTH(psrc[x+1]) +
1112 LICE_PIXEL_EIGHTH(lp);
1113 lp=tp;
1115 pdest[x] = LICE_PIXEL_HALF(psrc[x]) +
1116 LICE_PIXEL_QUARTER(lp) +
1117 LICE_PIXEL_QUARTER(psrc2[x]);
1119 else
1121 const LICE_pixel *psrc2=psrc-src_span;
1122 const LICE_pixel *psrc3=psrc+src_span;
1123 if (tmpbuf)
1124 psrc2=tmpbuf + ((i&1) ? 0 : w);
1126 LICE_pixel lp;
1127 pdest[0] = LICE_PIXEL_HALF(lp=psrc[0]) +
1128 LICE_PIXEL_QUARTER(psrc[1]) +
1129 LICE_PIXEL_EIGHTH(psrc2[0]) +
1130 LICE_PIXEL_EIGHTH(psrc3[0]);
1131 int x;
1132 for (x = 1; x < w-1; x ++)
1134 LICE_pixel tp;
1135 pdest[x] = LICE_PIXEL_HALF(tp=psrc[x]) +
1136 LICE_PIXEL_EIGHTH(psrc[x+1]) +
1137 LICE_PIXEL_EIGHTH(lp) +
1138 LICE_PIXEL_EIGHTH(psrc2[x]) +
1139 LICE_PIXEL_EIGHTH(psrc3[x]);
1140 lp=tp;
1142 pdest[x] = LICE_PIXEL_HALF(psrc[x]) +
1143 LICE_PIXEL_QUARTER(lp) +
1144 LICE_PIXEL_EIGHTH(psrc2[x]) +
1145 LICE_PIXEL_EIGHTH(psrc3[x]);
1147 pdest+=dest_span;
1148 psrc += src_span;
1150 if (tmpbuf && tmpbuf != turdbuf)
1151 free(tmpbuf);
1154 #endif
1156 #ifndef LICE_NO_BLIT_SUPPORT
1157 void LICE_ScaledBlit(LICE_IBitmap *dest, LICE_IBitmap *src,
1158 int dstx, int dsty, int dstw, int dsth,
1159 float srcx, float srcy, float srcw, float srch,
1160 float alpha, int mode)
1162 if (!dest || !src || !dstw || !dsth || !alpha) return;
1164 // non-scaling optimized omde
1165 if (fabs(srcw-dstw)<0.001 && fabs(srch-dsth)<0.001)
1167 // and if not bilinear filtering, or
1168 // the source coordinates are near their integer counterparts
1169 if ((mode&LICE_BLIT_FILTER_MASK)!=LICE_BLIT_FILTER_BILINEAR ||
1170 (fabs(srcx-floor(srcx+0.5f))<0.03 && fabs(srcy-floor(srcy+0.5f))<0.03))
1172 RECT sr={(int)(srcx+0.5f),(int)(srcy+0.5f),};
1173 sr.right=sr.left+dstw;
1174 sr.bottom=sr.top+dsth;
1175 LICE_Blit(dest,src,dstx,dsty,&sr,alpha,mode);
1176 return;
1180 #ifndef DISABLE_LICE_EXTENSIONS
1181 if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_SCALEDBLIT_ACCEL))
1183 LICE_Ext_ScaledBlit_acceldata data(src, dstx, dsty, dstw, dsth, srcx, srcy, srcw, srch, alpha, mode);
1184 if (dest->Extended(LICE_EXT_SCALEDBLIT_ACCEL, &data)) return;
1186 #endif
1188 if (dstw<0)
1190 dstw=-dstw;
1191 dstx-=dstw;
1192 srcx+=srcw;
1193 srcw=-srcw;
1195 if (dsth<0)
1197 dsth=-dsth;
1198 dsty-=dsth;
1199 srcy+=srch;
1200 srch=-srch;
1203 double xadvance = srcw / dstw;
1204 double yadvance = srch / dsth;
1206 if (dstx < 0) { srcx -= (float) (dstx*xadvance); dstw+=dstx; dstx=0; }
1207 if (dsty < 0) { srcy -= (float) (dsty*yadvance); dsth+=dsty; dsty=0; }
1209 const int destbm_w = dest->getWidth(), destbm_h = dest->getHeight();
1210 if (dstw < 1 || dsth < 1 || dstx >= destbm_w || dsty >= destbm_h) return;
1212 if (dstw > destbm_w-dstx) dstw=destbm_w-dstx;
1213 if (dsth > destbm_h-dsty) dsth=destbm_h-dsty;
1215 int idx=(int)(xadvance*65536.0);
1216 int idy=(int)(yadvance*65536.0);
1217 int icurx=(int) (srcx*65536.0);
1218 int icury=(int) (srcy*65536.0);
1221 #if 1
1222 // the clip area calculations need to be done fixed point so the results match runtime
1224 if (idx>0)
1226 if (icurx < 0) // increase dstx, decrease dstw
1228 int n = (idx-1-icurx)/idx;
1229 dstw-=n;
1230 dstx+=n;
1231 icurx+=idx*n;
1233 if ((icurx + idx*(dstw-1))/65536 >= src->getWidth())
1235 int neww = ((src->getWidth()-1)*65536 - icurx)/idx;
1236 if (neww < dstw) dstw=neww;
1239 else if (idx<0)
1241 // todo: optimize source-clipping with reversed X axis
1244 if (idy > 0)
1246 if (icury < 0) // increase dsty, decrease dsth
1248 int n = (idy-1-icury)/idy;
1249 dsth-=n;
1250 dsty+=n;
1251 icury+=idy*n;
1253 if ((icury + idy*(dsth-1))/65536 >= src->getHeight())
1255 int newh = ((src->getHeight()-1)*65536 - icury)/idy;
1256 if (newh < dsth) dsth=newh;
1259 else if (idy<0)
1261 // todo: optimize source-clipping with reversed Y axis (check icury against src->getHeight(), etc)
1263 if (dstw<1 || dsth<1) return;
1264 #endif
1267 int dest_span=dest->getRowSpan()*sizeof(LICE_pixel);
1268 int src_span=src->getRowSpan()*sizeof(LICE_pixel);
1270 const LICE_pixel_chan *psrc = (const LICE_pixel_chan *)src->getBits();
1271 LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits();
1272 if (!psrc || !pdest) return;
1275 if (src->isFlipped())
1277 psrc += (src->getHeight()-1)*src_span;
1278 src_span=-src_span;
1281 if (dest->isFlipped())
1283 pdest += (destbm_h-dsty - 1)*dest_span;
1284 dest_span=-dest_span;
1286 else pdest += dsty*dest_span;
1287 pdest+=dstx*sizeof(LICE_pixel);
1289 int clip_r=(int)(srcx+lice_max(srcw,0)+0.999999);
1290 int clip_b=(int)(srcy+lice_max(srch,0)+0.999999);
1291 if (clip_r>src->getWidth()) clip_r=src->getWidth();
1292 if (clip_b>src->getHeight()) clip_b=src->getHeight();
1294 if (clip_r<1||clip_b<1) return;
1296 int ia=(int)(alpha*256.0);
1298 if ((mode&(LICE_BLIT_FILTER_MASK|LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA))==LICE_BLIT_MODE_COPY && (ia==128 || ia==256))
1300 if (ia==128)
1302 _LICE_Template_Blit0<_LICE_CombinePixelsHalfMixFAST>::scaleBlitFAST(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span);
1304 else
1306 _LICE_Template_Blit0<_LICE_CombinePixelsClobberFAST>::scaleBlitFAST(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span);
1309 else
1311 if (xadvance>=1.7 && yadvance >=1.7 && (mode&LICE_BLIT_FILTER_MASK)==LICE_BLIT_FILTER_BILINEAR)
1313 int msc = lice_max(idx,idy);
1314 const int filtsz=msc>(3<<16) ? 5 : 3;
1315 const int filt_start = - (filtsz/2);
1317 int filter[25]; // 5x5 max
1319 int y;
1320 // char buf[4096];
1321 // sprintf(buf,"filter, msc=%f: ",msc);
1322 int *p=filter;
1323 for(y=0;y<filtsz;y++)
1325 int x;
1326 for(x=0;x<filtsz;x++)
1328 if (x==y && x==filtsz/2) *p++ = 65536; // src pix is always valued at 1.
1329 else
1331 double dx=x+filt_start;
1332 double dy=y+filt_start;
1333 double v = (msc-1.0) / sqrt(dx*dx+dy*dy); // this needs serious tweaking...
1335 // sprintf(buf+strlen(buf),"%f,",v);
1337 if(v<0.0) *p++=0;
1338 else if (v>1.0) *p++=65536;
1339 else *p++=(int)(v*65536.0);
1343 // OutputDebugString(buf);
1346 #ifdef LICE_FAVOR_SIZE
1347 LICE_COMBINEFUNC blitfunc=NULL;
1348 #define __LICE__ACTION(comb) blitfunc=comb::doPix;
1349 #else
1350 #define __LICE__ACTION(comb) _LICE_Template_Blit2<comb>::scaleBlitFilterDown(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span,ia,filter,filt_start,filtsz)
1351 #endif
1352 __LICE_ACTION_SRCALPHA(mode,ia,false);
1353 #undef __LICE__ACTION
1355 #ifdef LICE_FAVOR_SIZE
1356 if (blitfunc) _LICE_Template_Blit2::scaleBlitFilterDown(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span,ia,filter,filt_start,filtsz,blitfunc);
1357 #endif
1360 else
1362 #ifdef LICE_FAVOR_SIZE
1363 LICE_COMBINEFUNC blitfunc=NULL;
1364 #define __LICE__ACTION(comb) blitfunc=comb::doPix;
1365 #else
1366 #define __LICE__ACTION(comb) _LICE_Template_Blit2<comb>::scaleBlit(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK)
1367 #endif
1368 __LICE_ACTION_SRCALPHA(mode,ia,false);
1369 #undef __LICE__ACTION
1370 #ifdef LICE_FAVOR_SIZE
1371 if (blitfunc) _LICE_Template_Blit2::scaleBlit(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK,blitfunc);
1372 #endif
1377 void LICE_DeltaBlit(LICE_IBitmap *dest, LICE_IBitmap *src,
1378 int dstx, int dsty, int dstw, int dsth,
1379 float srcx, float srcy, float srcw, float srch,
1380 double dsdx, double dtdx, double dsdy, double dtdy,
1381 double dsdxdy, double dtdxdy,
1382 bool cliptosourcerect, float alpha, int mode)
1384 if (!dest || !src || !dstw || !dsth) return;
1386 double src_top=0.0,src_left=0.0,src_right=src->getWidth(),src_bottom=src->getHeight();
1388 if (cliptosourcerect)
1390 if (srcx > src_left) src_left=srcx;
1391 if (srcy > src_top) src_top=srcy;
1392 if (srcx+srcw < src_right) src_right=srcx+srcw;
1393 if (srcy+srch < src_bottom) src_bottom=srcy+srch;
1396 if (dstw<0)
1398 dstw=-dstw;
1399 dstx-=dstw;
1400 srcx+=srcw;
1402 if (dsth<0)
1404 dsth=-dsth;
1405 dsty-=dsth;
1406 srcy+=srch;
1410 if (dstx < 0)
1412 srcx -= (float) (dstx*dsdx);
1413 srcy -= (float) (dstx*dtdx);
1414 dstw+=dstx;
1415 dstx=0;
1417 if (dsty < 0)
1419 srcy -= (float) (dsty*dtdy);
1420 srcx -= (float) (dsty*dsdy);
1421 dsth+=dsty;
1422 dsty=0;
1425 const int destbm_w = dest->getWidth(), destbm_h = dest->getHeight();
1426 if (dstw < 1 || dsth < 1 || dstx >= destbm_w || dsty >= destbm_h) return;
1428 if (dstw > destbm_w-dstx) dstw=destbm_w-dstx;
1429 if (dsth > destbm_h-dsty) dsth=destbm_h-dsty;
1432 int dest_span=dest->getRowSpan()*sizeof(LICE_pixel);
1433 int src_span=src->getRowSpan()*sizeof(LICE_pixel);
1435 const LICE_pixel_chan *psrc = (LICE_pixel_chan *)src->getBits();
1436 LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits();
1437 if (!psrc || !pdest) return;
1439 if (src->isFlipped())
1441 psrc += (src->getHeight()-1)*src_span;
1442 src_span=-src_span;
1445 if (dest->isFlipped())
1447 pdest += (destbm_h-dsty - 1)*dest_span;
1448 dest_span=-dest_span;
1450 else pdest += dsty*dest_span;
1451 pdest+=dstx*sizeof(LICE_pixel);
1453 int sl=(int)(src_left);
1454 int sr=(int)(src_right);
1455 int st=(int)(src_top);
1456 int sb=(int)(src_bottom);
1458 sr -= sl;
1459 sb -= st;
1460 if (sr < 1 || sb < 1) return;
1462 psrc += src_span * st + sl * sizeof(LICE_pixel);
1464 int ia=(int)(alpha*256.0);
1465 int isrcx=(int)(srcx*65536.0);
1466 int isrcy=(int)(srcy*65536.0);
1467 int idsdx=(int)(dsdx*65536.0);
1468 int idtdx=(int)(dtdx*65536.0);
1469 int idsdy=(int)(dsdy*65536.0);
1470 int idtdy=(int)(dtdy*65536.0);
1471 int idsdxdy=(int)(dsdxdy*65536.0);
1472 int idtdxdy=(int)(dtdxdy*65536.0);
1474 #ifndef LICE_FAVOR_SPEED
1475 LICE_COMBINEFUNC blitfunc=NULL;
1476 #define __LICE__ACTION(comb) blitfunc = comb::doPix;
1477 #else
1478 #define __LICE__ACTION(comb) _LICE_Template_Blit3<comb>::deltaBlit(pdest,psrc,dstw,dsth,isrcx,isrcy,idsdx,idtdx,idsdy,idtdy,idsdxdy,idtdxdy,sr,sb,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK)
1479 #endif
1480 __LICE_ACTION_SRCALPHA(mode,ia,false);
1481 #undef __LICE__ACTION
1483 #ifndef LICE_FAVOR_SPEED
1484 if (blitfunc) _LICE_Template_Blit3::deltaBlit(pdest,psrc,dstw,dsth,isrcx,isrcy,idsdx,idtdx,idsdy,idtdy,idsdxdy,idtdxdy,sr,sb,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK,blitfunc);
1485 #endif
1489 void LICE_DeltaBlitAlpha(LICE_IBitmap *dest, LICE_IBitmap *src,
1490 int dstx, int dsty, int dstw, int dsth,
1491 float srcx, float srcy, float srcw, float srch,
1492 double dsdx, double dtdx, double dsdy, double dtdy,
1493 double dsdxdy, double dtdxdy,
1494 bool cliptosourcerect, float alpha, int mode, double dadx, double dady, double dadxdy)
1496 if (!dest || !src || !dstw || !dsth) return;
1498 const double eps = 0.0001;
1499 if (fabs(dadx*dstw) < eps && fabs(dady*dsth) < eps && fabs(dadxdy*dsth) < eps)
1501 LICE_DeltaBlit(dest, src, dstx, dsty, dstw, dsth, srcx, srcy, srcw, srch, dsdx, dtdx, dsdy, dtdy, dsdxdy, dtdxdy, cliptosourcerect, alpha, mode);
1502 return;
1505 double src_top=0.0,src_left=0.0,src_right=src->getWidth(),src_bottom=src->getHeight();
1507 if (cliptosourcerect)
1509 if (srcx > src_left) src_left=srcx;
1510 if (srcy > src_top) src_top=srcy;
1511 if (srcx+srcw < src_right) src_right=srcx+srcw;
1512 if (srcy+srch < src_bottom) src_bottom=srcy+srch;
1515 if (dstw<0)
1517 dstw=-dstw;
1518 dstx-=dstw;
1519 srcx+=srcw;
1521 if (dsth<0)
1523 dsth=-dsth;
1524 dsty-=dsth;
1525 srcy+=srch;
1529 if (dstx < 0)
1531 alpha -= (float) (dstx*dadx);
1532 srcx -= (float) (dstx*dsdx);
1533 srcy -= (float) (dstx*dtdx);
1534 dstw+=dstx;
1535 dstx=0;
1537 if (dsty < 0)
1539 alpha -= (float) (dsty*dady);
1540 srcy -= (float) (dsty*dtdy);
1541 srcx -= (float) (dsty*dsdy);
1542 dsth+=dsty;
1543 dsty=0;
1546 const int destbm_w = dest->getWidth(), destbm_h = dest->getHeight();
1547 if (dstw < 1 || dsth < 1 || dstx >= destbm_w || dsty >= destbm_h) return;
1549 if (dstw > destbm_w-dstx) dstw=destbm_w-dstx;
1550 if (dsth > destbm_h-dsty) dsth=destbm_h-dsty;
1553 int dest_span=dest->getRowSpan()*sizeof(LICE_pixel);
1554 int src_span=src->getRowSpan()*sizeof(LICE_pixel);
1556 const LICE_pixel_chan *psrc = (LICE_pixel_chan *)src->getBits();
1557 LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits();
1558 if (!psrc || !pdest) return;
1560 if (src->isFlipped())
1562 psrc += (src->getHeight()-1)*src_span;
1563 src_span=-src_span;
1566 if (dest->isFlipped())
1568 pdest += (destbm_h-dsty - 1)*dest_span;
1569 dest_span=-dest_span;
1571 else pdest += dsty*dest_span;
1572 pdest+=dstx*sizeof(LICE_pixel);
1574 int sl=(int)(src_left);
1575 int sr=(int)(src_right);
1576 int st=(int)(src_top);
1577 int sb=(int)(src_bottom);
1579 sr -= sl;
1580 sb -= st;
1581 if (sr < 1 || sb < 1) return;
1583 psrc += src_span * st + sl * sizeof(LICE_pixel);
1585 int ia=(int)(alpha*65536.0);
1586 int isrcx=(int)(srcx*65536.0);
1587 int isrcy=(int)(srcy*65536.0);
1588 int idsdx=(int)(dsdx*65536.0);
1589 int idtdx=(int)(dtdx*65536.0);
1590 int idsdy=(int)(dsdy*65536.0);
1591 int idtdy=(int)(dtdy*65536.0);
1592 int idsdxdy=(int)(dsdxdy*65536.0);
1593 int idtdxdy=(int)(dtdxdy*65536.0);
1595 int idadx=(int)(dadx*65536.0);
1596 int idady=(int)(dady*65536.0);
1597 int idadxdy=(int)(dadxdy*65536.0);
1599 #ifndef LICE_FAVOR_SPEED
1600 LICE_COMBINEFUNC blitfunc=NULL;
1601 #define __LICE__ACTION(comb) blitfunc = comb::doPix;
1602 #else
1603 #define __LICE__ACTION(comb) _LICE_Template_Blit4<comb>::deltaBlitAlpha(pdest,psrc,dstw,dsth,isrcx,isrcy,idsdx,idtdx,idsdy,idtdy,idsdxdy,idtdxdy,sr,sb,src_span,dest_span,ia,idadx,idady,idadxdy,mode&LICE_BLIT_FILTER_MASK)
1604 #endif
1605 __LICE_ACTION_NOSRCALPHA(mode,256,true);
1606 #undef __LICE__ACTION
1608 #ifndef LICE_FAVOR_SPEED
1609 if (blitfunc) _LICE_Template_Blit4::deltaBlitAlpha(pdest,psrc,dstw,dsth,isrcx,isrcy,idsdx,idtdx,idsdy,idtdy,idsdxdy,idtdxdy,sr,sb,src_span,dest_span,ia,idadx,idady,idadxdy,mode&LICE_BLIT_FILTER_MASK,blitfunc);
1610 #endif
1617 void LICE_RotatedBlit(LICE_IBitmap *dest, LICE_IBitmap *src,
1618 int dstx, int dsty, int dstw, int dsth,
1619 float srcx, float srcy, float srcw, float srch,
1620 float angle,
1621 bool cliptosourcerect, float alpha, int mode, float rotxcent, float rotycent)
1623 if (!dest || !src || !dstw || !dsth) return;
1625 double src_top=0.0,src_left=0.0,src_right=src->getWidth(),src_bottom=src->getHeight();
1627 if (cliptosourcerect)
1629 if (srcx > src_left) src_left=srcx;
1630 if (srcy > src_top) src_top=srcy;
1631 if (srcx+srcw < src_right) src_right=srcx+srcw;
1632 if (srcy+srch < src_bottom) src_bottom=srcy+srch;
1635 if (dstw<0)
1637 dstw=-dstw;
1638 dstx-=dstw;
1639 srcx+=srcw;
1640 srcw=-srcw;
1642 if (dsth<0)
1644 dsth=-dsth;
1645 dsty-=dsth;
1646 srcy+=srch;
1647 srch=-srch;
1650 double cosa=cos(angle);
1651 double sina=sin(angle);
1653 double xsc=srcw / dstw;
1654 double ysc=srch / dsth;
1656 double dsdx = xsc * cosa;
1657 double dtdy = ysc * cosa;
1658 double dsdy = xsc * sina;
1659 double dtdx = ysc * -sina;
1661 srcx -= (float) (0.5 * (dstw*dsdx + dsth*dsdy - srcw) - rotxcent);
1662 srcy -= (float) (0.5 * (dsth*dtdy + dstw*dtdx - srch) - rotycent);
1664 if (dstx < 0)
1666 srcx -= (float) (dstx*dsdx);
1667 srcy -= (float) (dstx*dtdx);
1668 dstw+=dstx;
1669 dstx=0;
1671 if (dsty < 0)
1673 srcy -= (float) (dsty*dtdy);
1674 srcx -= (float) (dsty*dsdy);
1675 dsth+=dsty;
1676 dsty=0;
1679 const int destbm_w = dest->getWidth(), destbm_h = dest->getHeight();
1680 if (dstw < 1 || dsth < 1 || dstx >= destbm_w || dsty >= destbm_h) return;
1682 if (dstw > destbm_w-dstx) dstw=destbm_w-dstx;
1683 if (dsth > destbm_h-dsty) dsth=destbm_h-dsty;
1686 int dest_span=dest->getRowSpan()*sizeof(LICE_pixel);
1687 int src_span=src->getRowSpan()*sizeof(LICE_pixel);
1689 const LICE_pixel_chan *psrc = (LICE_pixel_chan *)src->getBits();
1690 LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits();
1691 if (!psrc || !pdest) return;
1693 if (src->isFlipped())
1695 psrc += (src->getHeight()-1)*src_span;
1696 src_span=-src_span;
1699 if (dest->isFlipped())
1701 pdest += (destbm_h-dsty - 1)*dest_span;
1702 dest_span=-dest_span;
1704 else pdest += dsty*dest_span;
1705 pdest+=dstx*sizeof(LICE_pixel);
1707 int sl=(int)(src_left);
1708 int sr=(int)(src_right);
1709 int st=(int)(src_top);
1710 int sb=(int)(src_bottom);
1712 sr -= sl;
1713 sb -= st;
1714 if (sr < 1 || sb < 1) return;
1716 psrc += src_span * st + sl * sizeof(LICE_pixel);
1718 int ia=(int)(alpha*256.0);
1719 int isrcx=(int)(srcx*65536.0);
1720 int isrcy=(int)(srcy*65536.0);
1721 int idsdx=(int)(dsdx*65536.0);
1722 int idtdx=(int)(dtdx*65536.0);
1723 int idsdy=(int)(dsdy*65536.0);
1724 int idtdy=(int)(dtdy*65536.0);
1726 #ifndef LICE_FAVOR_SPEED
1727 LICE_COMBINEFUNC blitfunc=NULL;
1728 #define __LICE__ACTION(comb) blitfunc = comb::doPix;
1729 #else
1730 #define __LICE__ACTION(comb) _LICE_Template_Blit3<comb>::deltaBlit(pdest,psrc,dstw,dsth,isrcx,isrcy,idsdx,idtdx,idsdy,idtdy,0,0,sr,sb,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK)
1731 #endif
1732 __LICE_ACTION_SRCALPHA(mode,ia,false);
1733 #undef __LICE__ACTION
1735 #ifndef LICE_FAVOR_SPEED
1736 if (blitfunc) _LICE_Template_Blit3::deltaBlit(pdest,psrc,dstw,dsth,isrcx,isrcy,idsdx,idtdx,idsdy,idtdy,0,0,sr,sb,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK,blitfunc);
1737 #endif
1740 #endif
1743 void LICE_Clear(LICE_IBitmap *dest, LICE_pixel color)
1745 if (!dest) return;
1747 #ifndef DISABLE_LICE_EXTENSIONS
1748 if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_CLEAR_ACCEL))
1750 if (dest->Extended(LICE_EXT_CLEAR_ACCEL, &color)) return;
1752 #endif
1754 LICE_pixel *p=dest->getBits();
1755 int h=dest->getHeight();
1756 const int w=dest->getWidth();
1757 const int sp=dest->getRowSpan();
1758 if (!p || w<1 || h<1 || !sp) return;
1760 while (h-->0)
1762 int n=w;
1763 while (n--) *p++ = color;
1764 p+=sp-w;
1771 void LICE_MultiplyAddRect(LICE_IBitmap *dest, int x, int y, int w, int h,
1772 float rsc, float gsc, float bsc, float asc,
1773 float radd, float gadd, float badd, float aadd)
1775 if (!dest) return;
1777 if (x<0) { w+=x; x=0; }
1778 if (y<0) { h+=y; y=0; }
1780 LICE_pixel *p=dest->getBits();
1781 const int sp=dest->getRowSpan();
1782 const int destbm_w = dest->getWidth(), destbm_h = dest->getHeight();
1783 if (!p || !sp || w<1 || h < 1 || x >= destbm_w || y >= destbm_h) return;
1785 if (w>destbm_w-x) w=destbm_w-x;
1786 if (h>destbm_h-y) h=destbm_h-y;
1788 if (dest->isFlipped())
1790 p+=(destbm_h - y - h)*sp;
1792 else
1794 p+=sp*y;
1797 p += x;
1799 int ir=(int)(rsc*256.0);
1800 int ig=(int)(gsc*256.0);
1801 int ib=(int)(bsc*256.0);
1802 int ia=(int)(asc*256.0);
1803 int ir2=(int)(radd*256.0);
1804 int ig2=(int)(gadd*256.0);
1805 int ib2=(int)(badd*256.0);
1806 int ia2=(int)(aadd*256.0);
1808 while (h-->0)
1810 int n=w;
1811 while (n--)
1813 LICE_pixel_chan *ptr=(LICE_pixel_chan *)p++;
1814 _LICE_MakePixelClamp(ptr,(ptr[LICE_PIXEL_R]*ir+ir2)>>8,
1815 (ptr[LICE_PIXEL_G]*ig+ig2)>>8,
1816 (ptr[LICE_PIXEL_B]*ib+ib2)>>8,
1817 (ptr[LICE_PIXEL_A]*ia+ia2)>>8);
1819 p+=sp-w;
1823 void LICE_ProcessRect(LICE_IBitmap *dest, int x, int y, int w, int h, void (*procFunc)(LICE_pixel *p, void *parm), void *parm)
1825 if (!dest||!procFunc) return;
1827 if (x<0) { w+=x; x=0; }
1828 if (y<0) { h+=y; y=0; }
1830 LICE_pixel *p=dest->getBits();
1831 const int sp=dest->getRowSpan();
1832 const int destbm_w = dest->getWidth(), destbm_h = dest->getHeight();
1833 if (!p || !sp || w<1 || h < 1 || x >= destbm_w || y >= destbm_h) return;
1835 if (w>destbm_w-x) w=destbm_w-x;
1836 if (h>destbm_h-y) h=destbm_h-y;
1838 if (dest->isFlipped())
1840 p+=(destbm_h - y - h)*sp;
1842 else
1844 p+=sp*y;
1847 p += x;
1849 while (h--)
1851 LICE_pixel *pout=p;
1852 int n=w;
1853 while (n-->0) procFunc(pout++,parm);
1854 p+=sp;
1860 void LICE_FillRect(LICE_IBitmap *dest, int x, int y, int w, int h, LICE_pixel color, float alpha, int mode)
1862 if (!dest) return;
1864 #ifndef DISABLE_LICE_EXTENSIONS
1865 if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_FILLRECT_ACCEL))
1867 LICE_Ext_FillRect_acceldata data(x, y, w, h, color, alpha, mode);
1868 if (dest->Extended(LICE_EXT_FILLRECT_ACCEL, &data)) return;
1870 #endif
1872 if (mode & LICE_BLIT_USE_ALPHA) alpha *= LICE_GETA(color)/255.0f;
1874 LICE_pixel *p=dest->getBits();
1875 const int sp=dest->getRowSpan();
1877 if (x<0) { w+=x; x=0; }
1878 if (y<0) { h+=y; y=0; }
1879 const int destbm_w = dest->getWidth(), destbm_h = dest->getHeight();
1880 if (!alpha || !p || !sp || w<1 || h < 1 || x >= destbm_w || y >= destbm_h) return;
1882 if (w>destbm_w-x) w=destbm_w-x;
1883 if (h>destbm_h-y) h=destbm_h-y;
1885 if (dest->isFlipped())
1887 p+=(destbm_h - y - h)*sp;
1889 else
1891 p+=sp*y;
1894 p += x;
1896 const int ia=(int)(alpha*256.0);
1897 // copy, alpha=1, alpha=0.5, 0.25, 0.75 optimizations
1898 if ((mode&LICE_BLIT_MODE_MASK)==LICE_BLIT_MODE_COPY)
1900 if (ia==256)
1902 _LICE_Template_Blit0<_LICE_CombinePixelsClobberFAST>::solidBlitFAST(p,w,h,color,sp);
1903 return;
1905 if (ia==128)
1907 // we use _LICE_CombinePixelsHalfMix2 because we pre-halve color here
1908 _LICE_Template_Blit0<_LICE_CombinePixelsHalfMix2FAST>::solidBlitFAST(p,w,h,(color>>1)&0x7f7f7f7f,sp);
1909 return;
1911 if (ia==64)
1913 _LICE_Template_Blit0<_LICE_CombinePixelsQuarterMix2FAST>::solidBlitFAST(p,w,h,(color>>2)&0x3f3f3f3f,sp);
1914 return;
1916 if (ia==192)
1918 _LICE_Template_Blit0<_LICE_CombinePixelsThreeQuarterMix2FAST>::solidBlitFAST(p,w,h,
1919 ((color>>1)&0x7f7f7f7f)+((color>>2)&0x3f3f3f3f),sp);
1920 return;
1924 #ifdef LICE_FAVOR_SIZE_EXTREME
1925 LICE_COMBINEFUNC blitfunc=NULL;
1926 #define __LICE__ACTION(comb) blitfunc=comb::doPix;
1927 #else
1928 #define __LICE__ACTION(comb) _LICE_Template_Blit1<comb>::solidBlit((LICE_pixel_chan*)p,w,h,LICE_GETR(color),LICE_GETG(color),LICE_GETB(color),ia,sp*sizeof(LICE_pixel))
1929 #endif
1931 // we use __LICE_ACTION_NOSRCALPHA even though __LICE_ACTION_CONSTANTALPHA
1932 // is valid, sinc we optimized the 1.0f/0.5f cases above
1933 __LICE_ACTION_NOSRCALPHA(mode,ia,false);
1934 #undef __LICE__ACTION
1936 #ifdef LICE_FAVOR_SIZE_EXTREME
1937 if (blitfunc) _LICE_Template_Blit1::solidBlit((LICE_pixel_chan*)p,w,h,LICE_GETR(color),LICE_GETG(color),LICE_GETB(color),ia,sp*sizeof(LICE_pixel),blitfunc);
1938 #endif
1941 void LICE_ClearRect(LICE_IBitmap *dest, int x, int y, int w, int h, LICE_pixel mask, LICE_pixel orbits)
1943 if (!dest) return;
1944 LICE_pixel *p=dest->getBits();
1946 if (x<0) { w+=x; x=0; }
1947 if (y<0) { h+=y; y=0; }
1949 const int sp=dest->getRowSpan();
1950 const int destbm_w = dest->getWidth(), destbm_h = dest->getHeight();
1951 if (!p || !sp || w<1 || h < 1 || x >= destbm_w || y >= destbm_h) return;
1953 if (w>destbm_w-x) w=destbm_w-x;
1954 if (h>destbm_h-y) h=destbm_h-y;
1956 if (dest->isFlipped())
1958 p+=(destbm_h - y - h)*sp;
1960 else p+=sp*y;
1962 p += x;
1963 while (h-->0)
1965 int n=w;
1966 while (n--)
1968 *p = (*p&mask)|orbits;
1969 p++;
1971 p+=sp-w;
1976 LICE_pixel LICE_GetPixel(LICE_IBitmap *bm, int x, int y)
1978 if (!bm) return 0;
1980 #ifndef DISABLE_LICE_EXTENSIONS
1981 if (bm->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_GETPIXEL_ACCEL))
1983 LICE_Ext_GetPixel_acceldata data(x, y);
1984 if (bm->Extended(LICE_EXT_GETPIXEL_ACCEL, &data)) return data.px;
1986 #endif
1988 const LICE_pixel *px;
1989 if (!(px=bm->getBits()) || x < 0 || y < 0 || x >= bm->getWidth() || y>= bm->getHeight()) return 0;
1990 if (bm->isFlipped()) return px[(bm->getHeight()-1-y) * bm->getRowSpan() + x];
1991 return px[y * bm->getRowSpan() + x];
1994 void LICE_PutPixel(LICE_IBitmap *bm, int x, int y, LICE_pixel color, float alpha, int mode)
1996 if (!bm) return;
1998 #ifndef DISABLE_LICE_EXTENSIONS
1999 if (bm->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_PUTPIXEL_ACCEL))
2001 LICE_Ext_PutPixel_acceldata data(x, y, color, alpha, mode);
2002 if (bm->Extended(LICE_EXT_PUTPIXEL_ACCEL, &data)) return;
2004 #endif
2006 LICE_pixel *px;
2007 if (!(px=bm->getBits()) || x < 0 || y < 0 || x >= bm->getWidth() || y>= bm->getHeight()) return;
2009 if (bm->isFlipped()) px+=x+(bm->getHeight()-1-y)*bm->getRowSpan();
2010 else px+=x+y*bm->getRowSpan();
2012 int ia = (int)(alpha * 256.0f);
2013 if ((mode&LICE_BLIT_MODE_MASK)==LICE_BLIT_MODE_COPY)
2015 if (ia==256)
2017 *px = color;
2018 return;
2020 if (ia==128)
2022 *px = ((*px>>1)&0x7f7f7f7f) + ((color>>1)&0x7f7f7f7f);
2023 return;
2025 if (ia==64)
2027 *px = ((*px>>1)&0x7f7f7f7f) + ((*px>>2)&0x3f3f3f3f) + ((color>>2)&0x3f3f3f3f);
2028 return;
2030 if (ia==192)
2032 *px = ((*px>>2)&0x3f3f3f3f) + ((color>>1)&0x7f7f7f7f) + ((color>>2)&0x3f3f3f3f);
2033 return;
2036 #define __LICE__ACTION(comb) comb::doPix((LICE_pixel_chan *)px, LICE_GETR(color),LICE_GETG(color),LICE_GETB(color),LICE_GETA(color), ia)
2037 __LICE_ACTION_NOSRCALPHA(mode,ia,false);
2038 #undef __LICE__ACTION
2042 #ifndef LICE_NO_BLIT_SUPPORT
2044 template<class T> class LICE_TransformBlit_class
2046 public:
2047 static void blit(LICE_IBitmap *dest, LICE_IBitmap *src,
2048 int dstx, int dsty, int dstw, int dsth,
2049 const T *srcpoints, int div_w, int div_h, // srcpoints coords should be div_w*div_h*2 long, and be in source image coordinates
2050 float alpha, int mode)
2052 if (!dest || !src || dstw<1 || dsth<1 || div_w<2 || div_h<2) return;
2054 int cypos=dsty;
2055 double ypos=dsty;
2056 double dxpos=dstw/(float)(div_w-1);
2057 double dypos=dsth/(float)(div_h-1);
2058 int y;
2059 const T *curpoints=srcpoints;
2060 for (y = 0; y < div_h-1; y ++)
2062 int nypos=(int)((ypos+=dypos) + 0.5);
2063 int x;
2064 double xpos=dstx;
2065 int cxpos=dstx;
2067 if (nypos != cypos)
2069 double iy=1.0/(double)(nypos-cypos);
2070 for (x = 0; x < div_w-1; x ++)
2072 int nxpos=(int) ((xpos+=dxpos) + 0.5);
2073 if (nxpos != cxpos)
2075 int offs=x*2;
2076 double sx=curpoints[offs];
2077 double sy=curpoints[offs+1];
2078 double sw=curpoints[offs+2]-sx;
2079 double sh=curpoints[offs+3]-sy;
2081 offs+=div_w*2;
2082 double sxdiff=curpoints[offs]-sx;
2083 double sydiff=curpoints[offs+1]-sy;
2084 double sw3=curpoints[offs+2]-curpoints[offs];
2085 double sh3=curpoints[offs+3]-curpoints[offs+1];
2087 double ix=1.0/(double)(nxpos-cxpos);
2088 double dsdx=sw*ix;
2089 double dtdx=sh*ix;
2090 double dsdx2=sw3*ix;
2091 double dtdx2=sh3*ix;
2092 double dsdy=sxdiff*iy;
2093 double dtdy=sydiff*iy;
2094 double dsdxdy = (dsdx2-dsdx)*iy;
2095 double dtdxdy = (dtdx2-dtdx)*iy;
2097 LICE_DeltaBlit(dest,src,cxpos,cypos,nxpos-cxpos,nypos-cypos,
2098 (float)sx,(float)sy,(float)sw,(float)sh,
2099 dsdx,dtdx,dsdy,dtdy,dsdxdy,dtdxdy,false,alpha,mode);
2102 cxpos=nxpos;
2105 curpoints+=div_w*2;
2106 cypos=nypos;
2111 template<class T> class LICE_TransformBlitAlpha_class
2113 public:
2114 static void blit(LICE_IBitmap *dest, LICE_IBitmap *src,
2115 int dstx, int dsty, int dstw, int dsth,
2116 const T *srcpoints, int div_w, int div_h, // srcpoints coords should be div_w*div_h*2 long, and be in source image coordinates
2117 int mode)
2119 if (!dest || !src || dstw<1 || dsth<1 || div_w<2 || div_h<2) return;
2121 int cypos=dsty;
2122 double ypos=dsty;
2123 double dxpos=dstw/(float)(div_w-1);
2124 double dypos=dsth/(float)(div_h-1);
2125 int y;
2126 const T *curpoints=srcpoints;
2127 for (y = 0; y < div_h-1; y ++)
2129 int nypos=(int)((ypos+=dypos)+0.5);
2130 int x;
2131 double xpos=dstx;
2132 int cxpos=dstx;
2134 if (nypos != cypos)
2136 double iy=1.0/(double)(nypos-cypos);
2137 for (x = 0; x < div_w-1; x ++)
2139 int nxpos=(int) ((xpos+=dxpos)+0.5);
2140 if (nxpos != cxpos)
2142 int offs=x*3;
2143 double sx=curpoints[offs];
2144 double sy=curpoints[offs+1];
2145 double sa=curpoints[offs+2];
2146 double sw=curpoints[offs+3]-sx;
2147 double sh=curpoints[offs+4]-sy;
2148 double sa2 = curpoints[offs+5]-sa;
2150 offs+=div_w*3;
2151 double sxdiff=curpoints[offs]-sx;
2152 double sydiff=curpoints[offs+1]-sy;
2153 double sadiff=curpoints[offs+2]-sa;
2154 double sw3=curpoints[offs+3]-curpoints[offs];
2155 double sh3=curpoints[offs+4]-curpoints[offs+1];
2156 double sa3=curpoints[offs+5]-curpoints[offs+2];
2158 double ix=1.0/(double)(nxpos-cxpos);
2159 double dsdx=sw*ix;
2160 double dtdx=sh*ix;
2161 double dadx=sa2*ix;
2162 double dsdx2=sw3*ix;
2163 double dtdx2=sh3*ix;
2164 double dadx2=sa3*ix;
2165 double dsdy=sxdiff*iy;
2166 double dtdy=sydiff*iy;
2167 double dady=sadiff*iy;
2168 double dsdxdy = (dsdx2-dsdx)*iy;
2169 double dtdxdy = (dtdx2-dtdx)*iy;
2170 double dadxdy = (dadx2-dadx)*iy;
2172 LICE_DeltaBlitAlpha(dest,src,cxpos,cypos,nxpos-cxpos,nypos-cypos,
2173 (float)sx,(float)sy,(float)sw,(float)sh,
2174 dsdx,dtdx,dsdy,dtdy,dsdxdy,dtdxdy,false,sa,mode,dadx,dady,dadxdy);
2177 cxpos=nxpos;
2180 curpoints+=div_w*3;
2181 cypos=nypos;
2186 void LICE_TransformBlit(LICE_IBitmap *dest, LICE_IBitmap *src,
2187 int dstx, int dsty, int dstw, int dsth,
2188 const float *srcpoints, int div_w, int div_h, // srcpoints coords should be div_w*div_h*2 long, and be in source image coordinates
2189 float alpha, int mode)
2191 LICE_TransformBlit_class<float>::blit(dest,src,dstx,dsty,dstw,dsth,srcpoints,div_w,div_h,alpha,mode);
2193 void LICE_TransformBlit2(LICE_IBitmap *dest, LICE_IBitmap *src,
2194 int dstx, int dsty, int dstw, int dsth,
2195 const double *srcpoints, int div_w, int div_h, // srcpoints coords should be div_w*div_h*2 long, and be in source image coordinates
2196 float alpha, int mode)
2198 LICE_TransformBlit_class<double>::blit(dest,src,dstx,dsty,dstw,dsth,srcpoints,div_w,div_h,alpha,mode);
2202 void LICE_TransformBlit2Alpha(LICE_IBitmap *dest, LICE_IBitmap *src,
2203 int dstx, int dsty, int dstw, int dsth,
2204 const double *srcpoints, int div_w, int div_h, // srcpoints coords should be div_w*div_h*3 long, and be in source image coordinates+alpha
2205 int mode)
2207 LICE_TransformBlitAlpha_class<double>::blit(dest,src,dstx,dsty,dstw,dsth,srcpoints,div_w,div_h,mode);
2209 #endif
2211 #ifndef LICE_NO_MISC_SUPPORT
2213 void LICE_SetAlphaFromColorMask(LICE_IBitmap *dest, LICE_pixel color)
2215 if (!dest) return;
2216 LICE_pixel *p=dest->getBits();
2217 int h=dest->getHeight();
2218 int w=dest->getWidth();
2219 int sp=dest->getRowSpan();
2220 if (!p || w<1 || h<1 || sp<1) return;
2222 while (h-->0)
2224 int n=w;
2225 while (n--)
2227 if ((*p&LICE_RGBA(255,255,255,0)) == color) *p&=LICE_RGBA(255,255,255,0);
2228 else *p|=LICE_RGBA(0,0,0,255);
2229 p++;
2231 p+=sp-w;
2236 void LICE_SimpleFill(LICE_IBitmap *dest, int x, int y, LICE_pixel newcolor,
2237 LICE_pixel comparemask,
2238 LICE_pixel keepmask)
2240 if (!dest) return;
2241 int dw=dest->getWidth();
2242 int dh=dest->getHeight();
2243 int rowsize=dest->getRowSpan();
2244 if (x<0||x>=dw||y<0||y>=dh) return;
2245 LICE_pixel *ptr=dest->getBits();
2246 if (!ptr) return;
2247 ptr += rowsize*y;
2249 LICE_pixel compval=ptr[x]&comparemask;
2250 int ay;
2251 for (ay=y;ay<dh; ay++)
2253 if ((ptr[x]&comparemask)!=compval) break;
2254 ptr[x]=(ptr[x]&keepmask)|newcolor;
2256 int ax;
2257 for(ax=x+1;ax<dw;ax++)
2259 if ((ptr[ax]&comparemask)!=compval) break;
2260 ptr[ax]=(ptr[ax]&keepmask)|newcolor;
2262 ax=x;
2263 while (--ax>=0)
2265 if ((ptr[ax]&comparemask)!=compval) break;
2266 ptr[ax]=(ptr[ax]&keepmask)|newcolor;
2269 ptr+=rowsize;
2271 ptr =dest->getBits()+rowsize*y;
2273 ay=y;
2274 while (--ay>=0)
2276 ptr-=rowsize;
2277 if ((ptr[x]&comparemask)!=compval) break;
2278 ptr[x]=(ptr[x]&keepmask)|newcolor;
2280 int ax;
2281 for(ax=x+1;ax<dw;ax++)
2283 if ((ptr[ax]&comparemask)!=compval) break;
2284 ptr[ax]=(ptr[ax]&keepmask)|newcolor;
2286 ax=x;
2287 while (--ax>=0)
2289 if ((ptr[ax]&comparemask)!=compval) break;
2290 ptr[ax]=(ptr[ax]&keepmask)|newcolor;
2295 // VS6 instantiates this wrong as a template function, needs to be a template class
2296 template <class COMBFUNC> class GlyphDrawImpl
2298 public:
2299 static void DrawGlyph(const LICE_pixel_chan* srcalpha, LICE_pixel* destpx, int src_w, int src_h, LICE_pixel color, int span, int src_span, int aa)
2301 const int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color);
2303 int xi, yi;
2304 for (yi = 0; yi < src_h; ++yi, srcalpha += src_span, destpx += span) {
2305 const LICE_pixel_chan* tsrc = srcalpha;
2306 LICE_pixel* tdest = destpx;
2307 for (xi = 0; xi < src_w; ++xi, ++tsrc, ++tdest) {
2308 const LICE_pixel_chan v = *tsrc;
2309 if (v) { // glyphs should be expected to have a lot of "holes"
2310 COMBFUNC::doPix((LICE_pixel_chan*) tdest, r, g, b, a, v*aa/256);
2317 void LICE_DrawGlyphEx(LICE_IBitmap* dest, int x, int y, LICE_pixel color, const LICE_pixel_chan* alphas, int glyph_w, int glyph_span, int glyph_h, float alpha, int mode)
2319 if (!dest) return;
2321 #ifndef DISABLE_LICE_EXTENSIONS
2322 if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_DRAWGLYPH_ACCEL) && glyph_w == glyph_span)
2324 LICE_Ext_DrawGlyph_acceldata data(x, y, color, alphas, glyph_w, glyph_h, alpha, mode);
2325 if (dest->Extended(LICE_EXT_DRAWGLYPH_ACCEL, &data)) return;
2327 #endif
2329 const int ia= (int)(alpha*256.0f);
2331 int src_x = 0, src_y = 0, src_w = glyph_w, src_h = glyph_h;
2332 if (x <= -src_w || y <= -src_h) return;
2334 if (x < 0) {
2335 src_x -= x;
2336 src_w += x;
2337 x = 0;
2339 if (y < 0) {
2340 src_y -= y;
2341 src_h += y;
2342 y = 0;
2345 const int destbm_w = dest->getWidth(), destbm_h = dest->getHeight();
2346 if (src_w < 0 || src_h < 0 || x >= destbm_w || y >= destbm_h) return;
2348 if (src_h > destbm_h-y) src_h = destbm_h-y;
2349 if (src_w > destbm_w-x) src_w = destbm_w-x;
2351 if (src_w < 1 || src_h < 1) return;
2354 LICE_pixel* destpx = dest->getBits();
2355 int span = dest->getRowSpan();
2356 if (dest->isFlipped()) {
2357 destpx += (destbm_h-y-1)*span+x;
2358 span = -span;
2360 else {
2361 destpx += y*dest->getRowSpan()+x;
2364 const LICE_pixel_chan* srcalpha = alphas+src_y*glyph_span+src_x;
2366 #define __LICE__ACTION(COMBFUNC) GlyphDrawImpl<COMBFUNC>::DrawGlyph(srcalpha,destpx, src_w, src_h, color,span,glyph_span,ia)
2367 __LICE_ACTION_NOSRCALPHA(mode, ia, false);
2368 #undef __LICE__ACTION
2371 void LICE_DrawGlyph(LICE_IBitmap* dest, int x, int y, LICE_pixel color, const LICE_pixel_chan* alphas, int glyph_w, int glyph_h, float alpha, int mode)
2373 LICE_DrawGlyphEx(dest,x,y,color,alphas,glyph_w,glyph_w,glyph_h,alpha,mode);
2376 void LICE_HalveBlitAA(LICE_IBitmap *dest, LICE_IBitmap *src)
2378 if (!dest||!src) return;
2379 int w = dest->getWidth();
2380 if (w > src->getWidth()/2) w=src->getWidth()/2;
2381 int h = dest->getHeight();
2382 if (h > src->getHeight()/2) h=src->getHeight()/2;
2383 int src_span = src->getRowSpan();
2384 int dest_span = dest->getRowSpan();
2385 const LICE_pixel *srcptr = src->getBits();
2386 LICE_pixel *destptr = dest->getBits();
2388 while (h--)
2390 const LICE_pixel *sp = srcptr;
2391 const LICE_pixel *sp2 = srcptr+src_span;
2392 LICE_pixel *dp = destptr;
2393 int x=w/2;
2395 // this is begging for SSE intrinsics, but we never use this function so leave it as-is :)
2397 // perhaps we should use more precision rather than chopping each src pixel to 6 bits, but oh well
2398 while (x--) // unroll 2px at a time, about 5% faster on core2 and ICC
2400 int r1=((sp[0]>>2)&0x3f3f3f3f);
2401 int r2=((sp[2]>>2)&0x3f3f3f3f);
2402 r1 += ((sp[1]>>2)&0x3f3f3f3f);
2403 r2 += ((sp[3]>>2)&0x3f3f3f3f);
2404 dp[0] = r1 +
2405 ((sp2[0]>>2)&0x3f3f3f3f) +
2406 ((sp2[1]>>2)&0x3f3f3f3f);
2407 dp[1] = r2 +
2408 ((sp2[2]>>2)&0x3f3f3f3f) +
2409 ((sp2[3]>>2)&0x3f3f3f3f);
2410 sp+=4;
2411 sp2+=4;
2412 dp+=2;
2414 if (w&1)
2416 *dp =
2417 ((sp[0]>>2)&0x3f3f3f3f) +
2418 ((sp[1]>>2)&0x3f3f3f3f) +
2419 ((sp2[0]>>2)&0x3f3f3f3f) +
2420 ((sp2[1]>>2)&0x3f3f3f3f);
2422 srcptr+=src_span*2;
2423 destptr+=dest_span;
2427 #endif // LICE_NO_MISC_SUPPORT
2429 int LICE_BitmapCmp(LICE_IBitmap* a, LICE_IBitmap* b, int *coordsOut)
2431 return LICE_BitmapCmpEx(a,b,LICE_RGBA(255,255,255,255),coordsOut);
2434 int LICE_BitmapCmpEx(LICE_IBitmap* a, LICE_IBitmap* b, LICE_pixel mask, int *coordsOut)
2436 if (!a || !b) {
2437 if (!a && b) return -1;
2438 if (a && !b) return 1;
2439 return 0;
2442 int aw = a->getWidth(), bw = b->getWidth();
2443 if (aw != bw) return bw-aw;
2444 int ah = a->getHeight(), bh = b->getHeight();
2445 if (ah != bh) return bh-ah;
2447 //coordsOut
2448 const LICE_pixel *px1 = a->getBits();
2449 const LICE_pixel *px2 = b->getBits();
2450 int span1 = a->getRowSpan();
2451 int span2 = b->getRowSpan();
2452 if (a->isFlipped())
2454 px1+=span1*(ah-1);
2455 span1=-span1;
2457 if (b->isFlipped())
2459 px2+=span2*(ah-1);
2460 span2=-span2;
2463 int y;
2464 if (!coordsOut)
2466 if (mask == LICE_RGBA(255,255,255,255))
2467 for (y=0; y < ah; y ++)
2469 int a = memcmp(px1,px2,aw*sizeof(LICE_pixel));
2470 if (a) return a;
2471 px1+=span1;
2472 px2+=span2;
2474 else
2475 for (y=0; y < ah; y ++)
2477 const LICE_pixel *ptr1 = px1, *ptr2 = px2;
2478 int x=aw;
2479 while (x--)
2480 if ((*ptr1++ ^ *ptr2++) & mask) return true;
2481 px1+=span1;
2482 px2+=span2;
2485 else
2487 int x;
2489 // find first row that differs
2490 for (y=0; y < ah; y ++)
2492 // check left side
2493 for (x=0;x<aw && !((px1[x]^px2[x])&mask);x++);
2494 if (x < aw) break;
2496 px1+=span1;
2497 px2+=span2;
2499 if (y>=ah)
2501 memset(coordsOut,0,4*sizeof(int));
2502 return 0; // no differences
2505 int miny=y;
2506 int minx=x;
2507 // scan right edge of top differing row
2508 for (x=aw-1;x>minx && !((px1[x]^px2[x])&mask);x--);
2509 int maxx=x;
2511 // find last row that differs
2512 px1+=span1 * (ah-1-y);
2513 px2+=span2 * (ah-1-y);
2514 for (y = ah-1; y > miny; y --)
2516 int x;
2517 // check left side
2518 for (x=0;x<aw && !((px1[x]^px2[x])&mask);x++);
2519 if (x < aw) break;
2520 px1-=span1;
2521 px2-=span2;
2523 int maxy=y;
2525 if (y > miny)
2527 if (x < minx) minx=x;
2528 // scan right edge of bottom row that differs
2529 for (x=aw-1;x>maxx && !((px1[x]^px2[x])&mask);x--);
2530 maxx=x;
2534 // find min/max x that differ
2535 px1+=span1 * (miny+1-y);
2536 px2+=span2 * (miny+1-y);
2537 for (y=miny+1;y<maxy && (minx>0 || maxx<aw-1);y++)
2539 int x;
2540 for (x=0;x<minx && !((px1[x]^px2[x])&mask);x++);
2541 minx=x;
2542 for (x=aw-1;x>maxx && !((px1[x]^px2[x])&mask);x--);
2543 maxx=x;
2545 px1+=span1;
2546 px2+=span2;
2549 coordsOut[0]=minx;
2550 coordsOut[1]=miny;
2551 coordsOut[2]=maxx-minx+1;
2552 coordsOut[3]=maxy-miny+1;
2554 return 1;
2557 return 0;
2560 unsigned short _LICE_RGB2HSV_invtab[256]={ // 65536/idx - 1
2561 0, 0xffff, 0x7fff, 0x5554, 0x3fff, 0x3332, 0x2aa9, 0x2491,
2562 0x1fff, 0x1c70, 0x1998, 0x1744, 0x1554, 0x13b0, 0x1248, 0x1110,
2563 0x0fff, 0x0f0e, 0x0e37, 0x0d78, 0x0ccb, 0x0c2f, 0x0ba1, 0x0b20,
2564 0x0aa9, 0x0a3c, 0x09d7, 0x097a, 0x0923, 0x08d2, 0x0887, 0x0841,
2565 0x07ff, 0x07c0, 0x0786, 0x074f, 0x071b, 0x06ea, 0x06bb, 0x068f,
2566 0x0665, 0x063d, 0x0617, 0x05f3, 0x05d0, 0x05af, 0x058f, 0x0571,
2567 0x0554, 0x0538, 0x051d, 0x0504, 0x04eb, 0x04d3, 0x04bc, 0x04a6,
2568 0x0491, 0x047c, 0x0468, 0x0455, 0x0443, 0x0431, 0x0420, 0x040f,
2569 0x03ff, 0x03ef, 0x03df, 0x03d1, 0x03c2, 0x03b4, 0x03a7, 0x039a,
2570 0x038d, 0x0380, 0x0374, 0x0368, 0x035d, 0x0352, 0x0347, 0x033c,
2571 0x0332, 0x0328, 0x031e, 0x0314, 0x030b, 0x0302, 0x02f9, 0x02f0,
2572 0x02e7, 0x02df, 0x02d7, 0x02cf, 0x02c7, 0x02bf, 0x02b8, 0x02b0,
2573 0x02a9, 0x02a2, 0x029b, 0x0294, 0x028e, 0x0287, 0x0281, 0x027b,
2574 0x0275, 0x026f, 0x0269, 0x0263, 0x025d, 0x0258, 0x0252, 0x024d,
2575 0x0248, 0x0242, 0x023d, 0x0238, 0x0233, 0x022f, 0x022a, 0x0225,
2576 0x0221, 0x021c, 0x0218, 0x0213, 0x020f, 0x020b, 0x0207, 0x0203,
2577 0x01ff, 0x01fb, 0x01f7, 0x01f3, 0x01ef, 0x01eb, 0x01e8, 0x01e4,
2578 0x01e0, 0x01dd, 0x01d9, 0x01d6, 0x01d3, 0x01cf, 0x01cc, 0x01c9,
2579 0x01c6, 0x01c2, 0x01bf, 0x01bc, 0x01b9, 0x01b6, 0x01b3, 0x01b1,
2580 0x01ae, 0x01ab, 0x01a8, 0x01a5, 0x01a3, 0x01a0, 0x019d, 0x019b,
2581 0x0198, 0x0196, 0x0193, 0x0191, 0x018e, 0x018c, 0x0189, 0x0187,
2582 0x0185, 0x0182, 0x0180, 0x017e, 0x017c, 0x0179, 0x0177, 0x0175,
2583 0x0173, 0x0171, 0x016f, 0x016d, 0x016b, 0x0169, 0x0167, 0x0165,
2584 0x0163, 0x0161, 0x015f, 0x015d, 0x015b, 0x0159, 0x0157, 0x0156,
2585 0x0154, 0x0152, 0x0150, 0x014f, 0x014d, 0x014b, 0x0149, 0x0148,
2586 0x0146, 0x0145, 0x0143, 0x0141, 0x0140, 0x013e, 0x013d, 0x013b,
2587 0x013a, 0x0138, 0x0137, 0x0135, 0x0134, 0x0132, 0x0131, 0x012f,
2588 0x012e, 0x012d, 0x012b, 0x012a, 0x0128, 0x0127, 0x0126, 0x0124,
2589 0x0123, 0x0122, 0x0120, 0x011f, 0x011e, 0x011d, 0x011b, 0x011a,
2590 0x0119, 0x0118, 0x0117, 0x0115, 0x0114, 0x0113, 0x0112, 0x0111,
2591 0x0110, 0x010e, 0x010d, 0x010c, 0x010b, 0x010a, 0x0109, 0x0108,
2592 0x0107, 0x0106, 0x0105, 0x0104, 0x0103, 0x0102, 0x0101, 0x0100,
2596 #endif//__LICE_CPP_IMPLEMENTED__