00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #undef LOCAL_DEBUG
00023 #undef DO_CLOCKING
00024
00025 #ifdef _WIN32
00026 #include "win32/config.h"
00027 #else
00028 #include "config.h"
00029 #endif
00030
00031 #include <string.h>
00032 #if TIME_WITH_SYS_TIME
00033 # include <sys/time.h>
00034 # include <time.h>
00035 #else
00036 # if HAVE_SYS_TIME_H
00037 # include <sys/time.h>
00038 # else
00039 # include <time.h>
00040 # endif
00041 #endif
00042 #ifdef HAVE_UNISTD_H
00043 #include <unistd.h>
00044 #endif
00045 #ifdef HAVE_STDLIB_H
00046 #include <stdlib.h>
00047 #endif
00048 #ifdef HAVE_STDARG_H
00049 #include <stdarg.h>
00050 #endif
00051 #include <ctype.h>
00052
00053 #ifdef _WIN32
00054 # include "win32/afterbase.h"
00055 #else
00056 # include "afterbase.h"
00057 #endif
00058
00059 #include "asimage.h"
00060 #include "import.h"
00061 #include "export.h"
00062 #include "imencdec.h"
00063 #include "ascmap.h"
00064
00065
00066
00067
00068 static inline ASMappedColor *new_mapped_color( CARD32 red, CARD32 green, CARD32 blue, CARD32 indexed )
00069 {
00070 register ASMappedColor *pnew = malloc( sizeof( ASMappedColor ));
00071 if( pnew != NULL )
00072 {
00073 pnew->red = INDEX_UNSHIFT_RED (red) ;
00074 pnew->green = INDEX_UNSHIFT_GREEN(green) ;
00075 pnew->blue = INDEX_UNSHIFT_BLUE (blue) ;
00076 pnew->indexed = indexed ;
00077 pnew->count = 1 ;
00078 pnew->cmap_idx = -1 ;
00079 pnew->next = NULL ;
00080
00081 }
00082 return pnew;
00083 }
00084
00085 void
00086 add_index_color( ASSortedColorHash *index, CARD32 indexed, unsigned int slot, CARD32 red, CARD32 green, CARD32 blue )
00087 {
00088 ASSortedColorBucket *stack ;
00089 ASMappedColor **pnext ;
00090
00091 stack = &(index->buckets[slot]);
00092 pnext = &(stack->head);
00093
00094 ++(stack->count);
00095
00096 if( stack->tail )
00097 {
00098 if( indexed == stack->tail->indexed )
00099 {
00100 ++(stack->tail->count);
00101 return;
00102 }else if( indexed > stack->tail->indexed )
00103 pnext = &(stack->tail);
00104 }
00105 while( *pnext )
00106 {
00107 register ASMappedColor *pelem = *pnext ;
00108 if( pelem->indexed == indexed )
00109 {
00110 ++(pelem->count);
00111 return ;
00112 }else if( pelem->indexed > indexed )
00113 {
00114 register ASMappedColor *pnew = new_mapped_color( red, green, blue, indexed );
00115 if( pnew )
00116 {
00117 ++(index->count_unique);
00118 pnew->next = pelem ;
00119 *pnext = pnew ;
00120 return;
00121 }
00122 }
00123 pnext = &(pelem->next);
00124 }
00125
00126 if( (*pnext = new_mapped_color( red, green, blue, indexed )) != NULL )
00127 {
00128 stack->tail = (*pnext);
00129 ++(index->count_unique);
00130 }
00131 }
00132
00133 void destroy_colorhash( ASSortedColorHash *index, Bool reusable )
00134 {
00135 if( index )
00136 {
00137 int i ;
00138 for( i = 0 ; i < index->buckets_num ; i++ )
00139 while( index->buckets[i].head )
00140 {
00141 ASMappedColor *to_free = index->buckets[i].head;
00142 index->buckets[i].head = to_free->next ;
00143 free( to_free );
00144 }
00145 if( !reusable )
00146 {
00147 free( index->buckets );
00148 free( index );
00149 }
00150 }
00151 }
00152
00153 #ifdef LOCAL_DEBUG
00154 void
00155 check_colorindex_counts( ASSortedColorHash *index )
00156 {
00157 int i ;
00158 int count_unique = 0;
00159
00160 for( i = 0 ; i < index->buckets_num ; i++ )
00161 {
00162 register ASMappedColor *pelem = index->buckets[i].head ;
00163 int row_count = 0 ;
00164 while( pelem != NULL )
00165 {
00166 count_unique++ ;
00167 if( pelem->cmap_idx < 0 )
00168 row_count += pelem->count ;
00169 pelem = pelem->next ;
00170 }
00171 if( row_count != index->buckets[i].count )
00172 fprintf( stderr, "bucket %d counts-> %d : %d\n", i, row_count, index->buckets[i].count );
00173 }
00174 fprintf( stderr, "total unique-> %d : %d\n", count_unique, index->count_unique );
00175
00176 }
00177 #endif
00178
00179 void
00180 fix_colorindex_shortcuts( ASSortedColorHash *index )
00181 {
00182 int i ;
00183 int last_good = -1, next_good = -1;
00184
00185 index->last_found = -1 ;
00186
00187 for( i = 0 ; i < index->buckets_num ; i++ )
00188 {
00189 register ASMappedColor **pelem = &(index->buckets[i].head) ;
00190 register ASMappedColor **tail = &(index->buckets[i].tail) ;
00191 while( *pelem != NULL )
00192 {
00193 if( (*pelem)->cmap_idx < 0 )
00194 {
00195 ASMappedColor *to_free = *pelem ;
00196 *pelem = (*pelem)->next ;
00197 free( to_free );
00198 }else
00199 {
00200 *tail = *pelem ;
00201 pelem = &((*pelem)->next);
00202 }
00203 }
00204 }
00205 for( i = 0 ; i < index->buckets_num ; i++ )
00206 {
00207 if( next_good < 0 )
00208 {
00209 for( next_good = i ; next_good < index->buckets_num ; next_good++ )
00210 if( index->buckets[next_good].head )
00211 break;
00212 if( next_good >= index->buckets_num )
00213 next_good = last_good ;
00214 }
00215 if( index->buckets[i].head )
00216 {
00217 last_good = i;
00218 next_good = -1;
00219 }else
00220 {
00221 if( last_good < 0 || ( i-last_good >= next_good-i && i < next_good ) )
00222 index->buckets[i].good_offset = next_good-i ;
00223 else
00224 index->buckets[i].good_offset = last_good-i ;
00225 }
00226 }
00227 }
00228
00229
00230
00231 static inline void
00232 add_colormap_item( register ASColormapEntry *pentry, ASMappedColor *pelem, int cmap_idx )
00233 {
00234 pentry->red = pelem->red ;
00235 pentry->green = pelem->green ;
00236 pentry->blue = pelem->blue ;
00237 pelem->cmap_idx = cmap_idx ;
00238 LOCAL_DEBUG_OUT( "colormap entry added: %d: #%2.2X%2.2X%2.2X",cmap_idx, pelem->red, pelem->green, pelem->blue );
00239 }
00240
00241 unsigned int
00242 add_colormap_items( ASSortedColorHash *index, unsigned int start, unsigned int stop, unsigned int quota, unsigned int base, ASColormapEntry *entries )
00243 {
00244 int cmap_idx = 0 ;
00245 unsigned int i ;
00246 if( quota >= index->count_unique )
00247 {
00248 for( i = start ; i < stop ; i++ )
00249 {
00250 register ASMappedColor *pelem = index->buckets[i].head ;
00251 while ( pelem != NULL )
00252 {
00253 add_colormap_item( &(entries[cmap_idx]), pelem, base++ );
00254 index->buckets[i].count -= pelem->count ;
00255 ++cmap_idx ;
00256 pelem = pelem->next ;
00257 }
00258 }
00259 }else
00260 {
00261 int total = 0 ;
00262 int subcount = 0 ;
00263 ASMappedColor *best = NULL ;
00264 int best_slot = start;
00265 for( i = start ; i <= stop ; i++ )
00266 total += index->buckets[i].count ;
00267
00268 for( i = start ; i <= stop ; i++ )
00269 {
00270 register ASMappedColor *pelem = index->buckets[i].head ;
00271 while ( pelem != NULL )
00272 {
00273 if( pelem->cmap_idx < 0 )
00274 {
00275 if( best == NULL )
00276 {
00277 best = pelem ;
00278 best_slot = i ;
00279 }else if( best->count < pelem->count )
00280 {
00281 best = pelem ;
00282 best_slot = i ;
00283 }
00284 else if( best->count == pelem->count &&
00285 subcount >= (total>>2) && subcount <= (total>>1)*3 )
00286 {
00287 best = pelem ;
00288 best_slot = i ;
00289 }
00290 subcount += pelem->count*quota ;
00291 LOCAL_DEBUG_OUT( "count = %d subtotal = %d, quota = %d, idx = %d, i = %d, total = %d", pelem->count, subcount, quota, cmap_idx, i, total );
00292 if( subcount >= total )
00293 {
00294 add_colormap_item( &(entries[cmap_idx]), best, base++ );
00295 index->buckets[best_slot].count -= best->count ;
00296 ++cmap_idx ;
00297 subcount -= total ;
00298 best = NULL ;
00299 }
00300 }
00301 pelem = pelem->next ;
00302 }
00303 }
00304 }
00305 return cmap_idx ;
00306 }
00307
00308 ASColormap *
00309 color_hash2colormap( ASColormap *cmap, unsigned int max_colors )
00310 {
00311 unsigned int cmap_idx = 0 ;
00312 int i ;
00313 ASSortedColorHash *index = NULL ;
00314
00315 if( cmap == NULL || cmap->hash == NULL )
00316 return NULL;
00317
00318 index = cmap->hash ;
00319 cmap->count = MIN(max_colors,index->count_unique);
00320 cmap->entries = safemalloc( cmap->count*sizeof( ASColormapEntry) );
00321
00322 if( index->count_unique <= max_colors )
00323 {
00324 add_colormap_items( index, 0, index->buckets_num, index->count_unique, 0, cmap->entries);
00325 }else
00326 while( cmap_idx < max_colors )
00327 {
00328 long total = 0 ;
00329 long subcount = 0 ;
00330 int start_slot = 0 ;
00331 int quota = max_colors-cmap_idx ;
00332
00333 for( i = 0 ; i < index->buckets_num ; i++ )
00334 total += index->buckets[i].count ;
00335
00336 for( i = 0 ; i < index->buckets_num ; i++ )
00337 {
00338 subcount += index->buckets[i].count*quota ;
00339 LOCAL_DEBUG_OUT( "count = %d, subtotal = %ld, to_add = %ld, idx = %d, i = %d, total = %ld", index->buckets[i].count, subcount, subcount/total, cmap_idx, i, total );
00340 if( subcount >= total )
00341 {
00342 int to_add = subcount/total ;
00343 if( i == index->buckets_num-1 && to_add < (int)max_colors-(int)cmap_idx )
00344 to_add = max_colors-cmap_idx;
00345 cmap_idx += add_colormap_items( index, start_slot, i, to_add, cmap_idx, &(cmap->entries[cmap_idx]));
00346 subcount %= total;
00347 start_slot = i+1;
00348 }
00349 }
00350 if( quota == (int)max_colors-(int)cmap_idx )
00351 break;
00352 }
00353 fix_colorindex_shortcuts( index );
00354 return cmap;
00355 }
00356
00357 void destroy_colormap( ASColormap *cmap, Bool reusable )
00358 {
00359 if( cmap )
00360 {
00361 if( cmap->entries )
00362 free( cmap->entries );
00363 if( cmap->hash )
00364 destroy_colorhash( cmap->hash, False );
00365 if( !reusable )
00366 free( cmap );
00367 }
00368 }
00369
00370 int
00371 get_color_index( ASSortedColorHash *index, CARD32 indexed, unsigned int slot )
00372 {
00373 ASSortedColorBucket *stack ;
00374 ASMappedColor *pnext, *lesser ;
00375 int offset ;
00376
00377 if( index->last_found == indexed )
00378 return index->last_idx;
00379 index->last_found = indexed ;
00380
00381 LOCAL_DEBUG_OUT( "index = %lX(%ld), slot = %d, offset = %d", indexed, indexed, slot, index->buckets[slot].good_offset );
00382 if( (offset = index->buckets[slot].good_offset) != 0 )
00383 slot += offset ;
00384 stack = &(index->buckets[slot]);
00385 LOCAL_DEBUG_OUT( "first_good = %lX(%ld), last_good = %lX(%ld)", stack->head->indexed, stack->head->indexed, stack->tail->indexed, stack->tail->indexed );
00386 if( offset < 0 || stack->tail->indexed <= indexed )
00387 return (index->last_idx=stack->tail->cmap_idx);
00388 if( offset > 0 || stack->head->indexed >= indexed )
00389 return (index->last_idx=stack->head->cmap_idx);
00390
00391 lesser = stack->head ;
00392 for( pnext = lesser; pnext != NULL ; pnext = pnext->next )
00393 {
00394 LOCAL_DEBUG_OUT( "lesser = %lX(%ld), pnext = %lX(%ld)", lesser->indexed, lesser->indexed, pnext->indexed, pnext->indexed );
00395 if( pnext->indexed >= indexed )
00396 {
00397 index->last_idx = ( pnext->indexed-indexed > indexed-lesser->indexed )?
00398 lesser->cmap_idx : pnext->cmap_idx ;
00399 return index->last_idx;
00400 }
00401 lesser = pnext ;
00402 }
00403 return stack->tail->cmap_idx;
00404 }
00405
00406 int *
00407 colormap_asimage( ASImage *im, ASColormap *cmap, unsigned int max_colors, unsigned int dither, int opaque_threshold )
00408 {
00409 int *mapped_im = NULL;
00410 int buckets_num = MAX_COLOR_BUCKETS;
00411 ASImageDecoder *imdec ;
00412 CARD32 *a, *r, *g, *b ;
00413 START_TIME(started);
00414
00415 int *dst ;
00416 unsigned int y ;
00417 register int x ;
00418
00419 if( im == NULL || cmap == NULL || im->width == 0 )
00420 return NULL;
00421
00422 if((imdec = start_image_decoding( NULL , im,
00423 SCL_DO_ALL, 0, 0, im->width, 0, NULL)) == NULL )
00424 {
00425 LOCAL_DEBUG_OUT( "failed to start image decoding%s", "");
00426 return NULL;
00427 }
00428
00429 #if defined(LOCAL_DEBUG) && !defined(NO_DEBUG_OUTPUT)
00430 print_asimage( im, ASFLAGS_EVERYTHING, __FUNCTION__, __LINE__ );
00431 #endif
00432
00433 if( max_colors == 0 )
00434 max_colors = 256 ;
00435 if( dither == -1 )
00436 dither = 4 ;
00437 else if( dither >= 8 )
00438 dither = 7 ;
00439 switch( dither )
00440 {
00441 case 0 :
00442 case 1 :
00443 case 2 : buckets_num = 4096 ;
00444 break ;
00445 case 3 :
00446 case 4 : buckets_num = 1024 ;
00447 break ;
00448 case 5 :
00449 case 6 : buckets_num = 64 ;
00450 break ;
00451 case 7 : buckets_num = 8 ;
00452 break ;
00453 }
00454
00455 dst = mapped_im = safemalloc( im->width*im->height*sizeof(int));
00456 memset(cmap, 0x00, sizeof(ASColormap));
00457 cmap->hash = safecalloc( 1, sizeof(ASSortedColorHash) );
00458 cmap->hash->buckets = safecalloc( buckets_num, sizeof( ASSortedColorBucket ) );
00459 cmap->hash->buckets_num = buckets_num ;
00460
00461 a = imdec->buffer.alpha ;
00462 r = imdec->buffer.red ;
00463 g = imdec->buffer.green ;
00464 b = imdec->buffer.blue ;
00465
00466 for( y = 0 ; y < im->height ; y++ )
00467 {
00468 int red = 0, green = 0, blue = 0;
00469 int im_width = im->width ;
00470 imdec->decode_image_scanline( imdec );
00471 if( opaque_threshold > 0 && !cmap->has_opaque)
00472 {
00473 x = im->width ;
00474 while( --x >= 0 )
00475 if( a[x] != 0x00FF )
00476 {
00477 cmap->has_opaque = True;
00478 break;
00479 }
00480 }
00481 switch( dither )
00482 {
00483 case 0 :
00484 for( x = 0; x < im_width ; x++ )
00485 {
00486 if( (int)a[x] < opaque_threshold ) dst[x] = -1 ;
00487 else
00488 {
00489 red = INDEX_SHIFT_RED(r[x]);
00490 green = INDEX_SHIFT_GREEN(g[x]);
00491 blue = INDEX_SHIFT_BLUE(b[x]);
00492 dst[x] = MAKE_INDEXED_COLOR24(red,green,blue);
00493 add_index_color( cmap->hash, dst[x], ((dst[x]>>12)&0x0FFF), red, green, blue);
00494 }
00495 }
00496 break ;
00497 case 1 :
00498 for( x = 0; x < im_width ; x++ )
00499 {
00500 if( (int)a[x] < opaque_threshold ) dst[x] = -1 ;
00501 else
00502 {
00503 red = INDEX_SHIFT_RED(r[x]);
00504 green = INDEX_SHIFT_GREEN(g[x]);
00505 blue = INDEX_SHIFT_BLUE(b[x]);
00506 dst[x] = MAKE_INDEXED_COLOR21(red,green,blue);
00507 add_index_color( cmap->hash, dst[x], ((dst[x]>>12)&0x0FFF), red, green, blue);
00508 }
00509 }
00510 break ;
00511 case 2 :
00512 {
00513 for( x = 0 ; x < im_width ; ++x )
00514 {
00515 red = INDEX_SHIFT_RED ((red +r[x]>255)?255:red+r[x]);
00516 green = INDEX_SHIFT_GREEN((green+g[x]>255)?255:green+g[x]);
00517 blue = INDEX_SHIFT_BLUE ((blue +b[x]>255)?255:blue+b[x]);
00518 if( (int)a[x] < opaque_threshold )
00519 dst[x] = -1 ;
00520 else
00521 {
00522 dst[x] = MAKE_INDEXED_COLOR18(red,green,blue);
00523 add_index_color( cmap->hash, dst[x], ((dst[x]>>12)&0x0FFF), red, green, blue);
00524 }
00525 red = INDEX_UNESHIFT_RED(red,1)&0x01 ;
00526 green = INDEX_UNESHIFT_GREEN(green,1)&0x01 ;
00527 blue = INDEX_UNESHIFT_BLUE(blue,1) &0x01 ;
00528 }
00529 }
00530 break ;
00531 case 3 :
00532 {
00533 for( x = 0 ; x < im_width ; ++x )
00534 {
00535 red = INDEX_SHIFT_RED ((red +r[x]>255)?255:red+r[x]);
00536 green = INDEX_SHIFT_GREEN((green+g[x]>255)?255:green+g[x]);
00537 blue = INDEX_SHIFT_BLUE ((blue +b[x]>255)?255:blue+b[x]);
00538 LOCAL_DEBUG_OUT( "alpha(%d,%d) = %ld, threshold = %d", x, y, a[x], opaque_threshold );
00539 if( (int)a[x] < opaque_threshold )
00540 dst[x] = -1 ;
00541 else
00542 {
00543 dst[x] = MAKE_INDEXED_COLOR15(red,green,blue);
00544 add_index_color( cmap->hash, dst[x], ((dst[x]>>14)&0x03FF), red, green, blue);
00545 }
00546 red = INDEX_UNESHIFT_RED(red,1) &0x03 ;
00547 green = INDEX_UNESHIFT_GREEN(green,1)&0x03 ;
00548 blue = INDEX_UNESHIFT_BLUE(blue,1) &0x03 ;
00549 }
00550 }
00551 break ;
00552 case 4 :
00553 {
00554 for( x = 0 ; x < im_width ; ++x )
00555 {
00556 red = INDEX_SHIFT_RED ((red +r[x]>255)?255:red+r[x]);
00557 green = INDEX_SHIFT_GREEN((green+g[x]>255)?255:green+g[x]);
00558 blue = INDEX_SHIFT_BLUE ((blue +b[x]>255)?255:blue+b[x]);
00559 if( (int)a[x] < opaque_threshold )
00560 dst[x] = -1 ;
00561 else
00562 {
00563 dst[x] = MAKE_INDEXED_COLOR12(red,green,blue);
00564 add_index_color( cmap->hash, dst[x], ((dst[x]>>14)&0x3FF), red, green, blue);
00565 }
00566 red = INDEX_UNESHIFT_RED(red,1) &0x07 ;
00567 green = INDEX_UNESHIFT_GREEN(green,1)&0x07 ;
00568 blue = INDEX_UNESHIFT_BLUE(blue,1) &0x07 ;
00569 }
00570 }
00571 break ;
00572 case 5 :
00573 {
00574 for( x = 0 ; x < im_width ; ++x )
00575 {
00576 red = INDEX_SHIFT_RED ((red +r[x]>255)?255:red+r[x]);
00577 green = INDEX_SHIFT_GREEN((green+g[x]>255)?255:green+g[x]);
00578 blue = INDEX_SHIFT_BLUE ((blue +b[x]>255)?255:blue+b[x]);
00579 if( (int)a[x] < opaque_threshold )
00580 dst[x] = -1 ;
00581 else
00582 {
00583 dst[x] = MAKE_INDEXED_COLOR9(red,green,blue);
00584 add_index_color( cmap->hash, dst[x], ((dst[x]>>18)&0x03F), red, green, blue);
00585 }
00586 red = INDEX_UNESHIFT_RED(red,1)&0x0F ;
00587 green = INDEX_UNESHIFT_GREEN(green,1)&0x0F ;
00588 blue = INDEX_UNESHIFT_BLUE(blue,1) &0x0F ;
00589 }
00590 }
00591 break ;
00592 case 6 :
00593 {
00594 for( x = 0 ; x < im_width ; ++x )
00595 {
00596 red = INDEX_SHIFT_RED ((red +r[x]>255)?255:red+r[x]);
00597 green = INDEX_SHIFT_GREEN((green+g[x]>255)?255:green+g[x]);
00598 blue = INDEX_SHIFT_BLUE ((blue +b[x]>255)?255:blue+b[x]);
00599 if( (int)a[x] < opaque_threshold )
00600 dst[x] = -1 ;
00601 else
00602 {
00603 dst[x] = MAKE_INDEXED_COLOR6(red,green,blue);
00604 add_index_color( cmap->hash, dst[x], ((dst[x]>>18)&0x03F), red, green, blue);
00605 }
00606 red = INDEX_UNESHIFT_RED(red,1)&0x01F ;
00607 green = INDEX_UNESHIFT_GREEN(green,1)&0x01F ;
00608 blue = INDEX_UNESHIFT_BLUE(blue,1) &0x01F ;
00609 }
00610 }
00611 break ;
00612 case 7 :
00613 {
00614 for( x = 0 ; x < im_width ; ++x )
00615 {
00616 red = INDEX_SHIFT_RED ((red +r[x]>255)?255:red+r[x]);
00617 green = INDEX_SHIFT_GREEN((green+g[x]>255)?255:green+g[x]);
00618 blue = INDEX_SHIFT_BLUE ((blue +b[x]>255)?255:blue+b[x]);
00619 if( (int)a[x] < opaque_threshold )
00620 dst[x] = -1 ;
00621 else
00622 {
00623 dst[x] = MAKE_INDEXED_COLOR3(red,green,blue);
00624 add_index_color( cmap->hash, dst[x], ((dst[x]>>21)&0x07), red, green, blue);
00625 }
00626 red = INDEX_UNESHIFT_RED(red,1)&0x03F ;
00627 green = INDEX_UNESHIFT_GREEN(green,1)&0x03F ;
00628 blue = INDEX_UNESHIFT_BLUE(blue,1) &0x03F ;
00629 }
00630 }
00631 break ;
00632 }
00633 dst += im_width ;
00634 }
00635 stop_image_decoding( &imdec );
00636 SHOW_TIME("color indexing",started);
00637
00638 #ifdef LOCAL_DEBUG
00639 check_colorindex_counts( cmap->hash );
00640 #endif
00641
00642 LOCAL_DEBUG_OUT("building colormap%s","");
00643 color_hash2colormap( cmap, max_colors );
00644 SHOW_TIME("colormap calculation",started);
00645
00646 #ifdef LOCAL_DEBUG
00647 check_colorindex_counts( cmap->hash );
00648 #endif
00649
00650 dst = mapped_im ;
00651 for( y = 0 ; y < im->height ; ++y )
00652 {
00653 switch( dither )
00654 {
00655 case 0 :
00656 case 1 :
00657 case 2 :
00658 for( x = 0 ; x < (int)im->width ; ++x )
00659 {
00660 LOCAL_DEBUG_OUT( "Mapping color at (%dx%d) indexed = %X", x, y, dst[x] );
00661 if( dst[x] >= 0 )
00662 dst[x] = get_color_index( cmap->hash, dst[x], ((dst[x]>>12)&0x0FFF));
00663 else
00664 dst[x] = cmap->count ;
00665 }
00666 break;
00667 case 3 :
00668 case 4 :
00669 for( x = 0 ; x < (int)im->width ; ++x )
00670 {
00671 LOCAL_DEBUG_OUT( "Mapping color at (%dx%d) indexed = %X", x, y, dst[x] );
00672 if( dst[x] >= 0 )
00673 dst[x] = get_color_index( cmap->hash, dst[x], ((dst[x]>>14)&0x03FF));
00674 else
00675 dst[x] = cmap->count ;
00676 }
00677 break;
00678 case 5 :
00679 case 6 :
00680 for( x = 0 ; x < (int)im->width ; ++x )
00681 if( dst[x] >= 0 )
00682 dst[x] = get_color_index( cmap->hash, dst[x], ((dst[x]>>18)&0x03F));
00683 else
00684 dst[x] = cmap->count ;
00685 break ;
00686 case 7 :
00687 for( x = 0 ; x < (int)im->width ; ++x )
00688 if( dst[x] >= 0 )
00689 dst[x] = get_color_index( cmap->hash, dst[x], ((dst[x]>>21)&0x007));
00690 else
00691 dst[x] = cmap->count ;
00692 break ;
00693 }
00694 dst += im->width ;
00695 }
00696
00697 return mapped_im ;
00698 }
00699