jdk/src/java.desktop/share/native/libmlib_image/mlib_ImageColorTrue2Index.c
changeset 38415 acea5f7d354b
parent 38414 3e22d8fd4912
child 38416 dd0b515bc286
equal deleted inserted replaced
38414:3e22d8fd4912 38415:acea5f7d354b
     1 /*
       
     2  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 /*
       
    27  * FUNCTION
       
    28  *      mlib_ImageColorTrue2Index - convert a true color image to an indexed
       
    29  *                                  color image
       
    30  *
       
    31  * SYNOPSIS
       
    32  *      mlib_status mlib_ImageColorTrue2Index(mlib_image       *dst,
       
    33  *                                            const mlib_image *src,
       
    34  *                                            const void       *colormap)
       
    35  *
       
    36  * ARGUMENTS
       
    37  *      colormap  Internal data structure for inverse color mapping.
       
    38  *      dst       Pointer to destination image.
       
    39  *      src       Pointer to source image.
       
    40  *
       
    41  * DESCRIPTION
       
    42  *      Convert a true color image to a pseudo color image with the method
       
    43  *      of finding the nearest matched lut entry for each pixel.
       
    44  *
       
    45  *      The src can be an MLIB_BYTE or MLIB_SHORT image with 3 or 4 channels.
       
    46  *      The dst must be a 1-channel MLIB_BYTE or MLIB_SHORT image.
       
    47  *
       
    48  *      The lut might have either 3 or 4 channels. The type of the lut can be
       
    49  *      one of the following:
       
    50  *              MLIB_BYTE in, MLIB_BYTE out (i.e., BYTE-to-BYTE)
       
    51  *              MLIB_BYTE in, MLIB_SHORT out (i.e., BYTE-to-SHORT)
       
    52  *              MLIB_SHORT in, MLIB_SHORT out (i.e., SHORT-to-SHORT)
       
    53  *              MLIB_SHORT in, MLIB_BYTE out (i.e., SHORT-to-BYTE)
       
    54  *
       
    55  *      The src image and the lut must have same number of channels.
       
    56  */
       
    57 
       
    58 #include "mlib_image.h"
       
    59 #include "mlib_ImageColormap.h"
       
    60 #include "mlib_ImageCheck.h"
       
    61 
       
    62 /***************************************************************/
       
    63 
       
    64 /*#define USE_VIS_CODE*/
       
    65 
       
    66 #ifdef USE_VIS_CODE
       
    67 #include "vis_proto.h"
       
    68 #define VIS_ALIGNADDR(X, Y)  vis_alignaddr((void *)(X), (Y))
       
    69 #endif
       
    70 
       
    71 /***************************************************************/
       
    72 
       
    73 #define LUT_BYTE_COLORS_3CHANNELS  1000
       
    74 #define LUT_BYTE_COLORS_4CHANNELS  3000
       
    75 #define LUT_SHORT_COLORS_3CHANNELS 1000
       
    76 #define LUT_SHORT_COLORS_4CHANNELS 1000
       
    77 
       
    78 /***************************************************************/
       
    79 
       
    80 #define MAIN_COLORTRUE2INDEX_LOOP( FROM_TYPE, TO_TYPE, NCHANNELS )       \
       
    81   for( y = 0; y < height; y++ )                                          \
       
    82   {                                                                      \
       
    83     mlib_ImageColorTrue2IndexLine_##FROM_TYPE##_##TO_TYPE##_##NCHANNELS( \
       
    84       sdata, ddata, width, colormap );                                   \
       
    85                                                                          \
       
    86     sdata += sstride;                                                    \
       
    87     ddata += dstride;                                                    \
       
    88   }
       
    89 
       
    90 /***************************************************************/
       
    91 
       
    92 #define COLOR_CUBE_U8_3_SEARCH( TABLE_POINTER_TYPE, SHIFT, STEP ) \
       
    93 {                                                                 \
       
    94   const mlib_u8 *c0, *c1, *c2;                                    \
       
    95   TABLE_POINTER_TYPE *table = s->table;                           \
       
    96   mlib_s32 bits = s->bits;                                        \
       
    97   mlib_s32 nbits = 8 - bits;                                      \
       
    98   mlib_s32 mask = ~( ( 1 << nbits ) - 1 );                        \
       
    99   mlib_s32 j;                                                     \
       
   100                                                                   \
       
   101   c0 = src + SHIFT;                                               \
       
   102   c1 = src + 1 + SHIFT;                                           \
       
   103   c2 = src + 2 + SHIFT;                                           \
       
   104                                                                   \
       
   105   switch( bits )                                                  \
       
   106   {                                                               \
       
   107     case 1:                                                       \
       
   108     case 2:                                                       \
       
   109     {                                                             \
       
   110       mlib_s32 bits0 = 8 - bits;                                  \
       
   111       mlib_s32 bits1 = bits0 - bits;                              \
       
   112       mlib_s32 bits2 = bits1 - bits;                              \
       
   113                                                                   \
       
   114       for( j = 0; j < length; j++ )                               \
       
   115       {                                                           \
       
   116         dst[ j ] = table[ ( ( *c0 & mask ) >> bits2 ) |           \
       
   117           ( ( *c1 & mask ) >> bits1 ) |                           \
       
   118           ( ( *c2 & mask ) >> bits0 ) ];                          \
       
   119                                                                   \
       
   120         c0 += STEP;                                               \
       
   121         c1 += STEP;                                               \
       
   122         c2 += STEP;                                               \
       
   123       }                                                           \
       
   124       break;                                                      \
       
   125     }                                                             \
       
   126     case 3:                                                       \
       
   127     {                                                             \
       
   128       for( j = 0; j < length; j++ )                               \
       
   129       {                                                           \
       
   130         dst[ j ] = table[ ( ( *c0 & mask ) << 1 ) |               \
       
   131           ( ( *c1 & mask ) >> 2 ) |                               \
       
   132           ( ( *c2 & mask ) >> 5 ) ];                              \
       
   133                                                                   \
       
   134         c0 += STEP;                                               \
       
   135         c1 += STEP;                                               \
       
   136         c2 += STEP;                                               \
       
   137       }                                                           \
       
   138       break;                                                      \
       
   139     }                                                             \
       
   140     case 4:                                                       \
       
   141     {                                                             \
       
   142       for( j = 0; j < length; j++ )                               \
       
   143       {                                                           \
       
   144         dst[ j ] = table[ ( ( *c0 & mask ) << 4 ) |               \
       
   145           ( *c1 & mask ) |                                        \
       
   146           ( ( *c2 & mask ) >> 4 ) ];                              \
       
   147                                                                   \
       
   148         c0 += STEP;                                               \
       
   149         c1 += STEP;                                               \
       
   150         c2 += STEP;                                               \
       
   151       }                                                           \
       
   152       break;                                                      \
       
   153     }                                                             \
       
   154     case 5:                                                       \
       
   155     case 6:                                                       \
       
   156     case 7:                                                       \
       
   157     {                                                             \
       
   158       mlib_s32 bits0 = 8 - bits;                                  \
       
   159       mlib_s32 bits1 = bits * 2 - 8;                              \
       
   160       mlib_s32 bits2 = bits1 + bits;                              \
       
   161                                                                   \
       
   162       for( j = 0; j < length; j++ )                               \
       
   163       {                                                           \
       
   164         dst[ j ] = table[ ( ( *c0 & mask ) << bits2 ) |           \
       
   165           ( ( *c1 & mask ) << bits1 ) |                           \
       
   166           ( ( *c2 & mask ) >> bits0 ) ];                          \
       
   167                                                                   \
       
   168         c0 += STEP;                                               \
       
   169         c1 += STEP;                                               \
       
   170         c2 += STEP;                                               \
       
   171       }                                                           \
       
   172       break;                                                      \
       
   173     }                                                             \
       
   174     case 8:                                                       \
       
   175     {                                                             \
       
   176       for( j = 0; j < length; j++ )                               \
       
   177       {                                                           \
       
   178         dst[ j ] = table[ ( ( *c0 & mask ) << 16 ) |              \
       
   179           ( ( *c1 & mask ) << 8 ) |                               \
       
   180           ( *c2 & mask ) ];                                       \
       
   181                                                                   \
       
   182         c0 += STEP;                                               \
       
   183         c1 += STEP;                                               \
       
   184         c2 += STEP;                                               \
       
   185       }                                                           \
       
   186       break;                                                      \
       
   187     }                                                             \
       
   188   }                                                               \
       
   189 }
       
   190 
       
   191 /***************************************************************/
       
   192 #define COLOR_CUBE_U8_4_SEARCH( TABLE_TYPE )                    \
       
   193 {                                                               \
       
   194   const mlib_u8 *c0, *c1, *c2, *c3;                             \
       
   195   TABLE_TYPE *table = s->table;                                 \
       
   196   mlib_s32 bits = s->bits;                                      \
       
   197   mlib_s32 nbits = 8 - bits;                                    \
       
   198   mlib_s32 mask = ~( ( 1 << nbits ) - 1 );                      \
       
   199   mlib_s32 j;                                                   \
       
   200                                                                 \
       
   201   c0 = src;                                                     \
       
   202   c1 = src + 1;                                                 \
       
   203   c2 = src + 2;                                                 \
       
   204   c3 = src + 3;                                                 \
       
   205                                                                 \
       
   206   switch( bits )                                                \
       
   207   {                                                             \
       
   208     case 1:                                                     \
       
   209     {                                                           \
       
   210       for( j = 0; j < length; j++ )                             \
       
   211       {                                                         \
       
   212         dst[ j ] = table[ ( ( *c0 & mask ) >> 4 ) |             \
       
   213           ( ( *c1 & mask ) >> 5 ) |                             \
       
   214           ( ( *c2 & mask ) >> 6 ) |                             \
       
   215           ( ( *c3 & mask ) >> 7 ) ];                            \
       
   216                                                                 \
       
   217         c0 += 4;                                                \
       
   218         c1 += 4;                                                \
       
   219         c2 += 4;                                                \
       
   220         c3 += 4;                                                \
       
   221       }                                                         \
       
   222       break;                                                    \
       
   223     }                                                           \
       
   224     case 2:                                                     \
       
   225     {                                                           \
       
   226       for( j = 0; j < length; j++ )                             \
       
   227       {                                                         \
       
   228         dst[ j ] = table[ ( *c0 & mask ) |                      \
       
   229           ( ( *c1 & mask ) >> 2 ) |                             \
       
   230           ( ( *c2 & mask ) >> 4 ) |                             \
       
   231           ( ( *c3 & mask ) >> 6 ) ];                            \
       
   232                                                                 \
       
   233         c0 += 4;                                                \
       
   234         c1 += 4;                                                \
       
   235         c2 += 4;                                                \
       
   236         c3 += 4;                                                \
       
   237           }                                                     \
       
   238       break;                                                    \
       
   239     }                                                           \
       
   240     case 3:                                                     \
       
   241     {                                                           \
       
   242       for( j = 0; j < length; j++ )                             \
       
   243       {                                                         \
       
   244         dst[ j ] = table[ ( ( *c0 & mask ) << 4 ) |             \
       
   245           ( ( *c1 & mask ) << 1 ) |                             \
       
   246           ( ( *c2 & mask ) >> 2 ) |                             \
       
   247           ( ( *c3 & mask ) >> 5 ) ];                            \
       
   248                                                                 \
       
   249         c0 += 4;                                                \
       
   250         c1 += 4;                                                \
       
   251         c2 += 4;                                                \
       
   252         c3 += 4;                                                \
       
   253       }                                                         \
       
   254       break;                                                    \
       
   255     }                                                           \
       
   256     case 4:                                                     \
       
   257     {                                                           \
       
   258       for( j = 0; j < length; j++ )                             \
       
   259       {                                                         \
       
   260         dst[ j ] = table[ ( ( *c0 & mask ) << 8 ) |             \
       
   261           ( ( *c1 & mask ) << 4 ) |                             \
       
   262           ( *c2 & mask ) |                                      \
       
   263           ( ( *c3 & mask ) >> 4 ) ];                            \
       
   264                                                                 \
       
   265         c0 += 4;                                                \
       
   266         c1 += 4;                                                \
       
   267         c2 += 4;                                                \
       
   268         c3 += 4;                                                \
       
   269       }                                                         \
       
   270       break;                                                    \
       
   271     }                                                           \
       
   272     case 5:                                                     \
       
   273     case 6:                                                     \
       
   274     {                                                           \
       
   275       mlib_s32 bits3 = bits * 4 - 8;                            \
       
   276       mlib_s32 bits2 = bits3 - bits;                            \
       
   277       mlib_s32 bits1 = bits2 - bits;                            \
       
   278       mlib_s32 bits0 = 8 - bits;                                \
       
   279                                                                 \
       
   280       for( j = 0; j < length; j++ )                             \
       
   281       {                                                         \
       
   282         dst[ j ] = table[ ( ( *c0 & mask ) << bits3 ) |         \
       
   283           ( ( *c1 & mask ) << bits2 ) |                         \
       
   284           ( ( *c2 & mask ) << bits1 ) |                         \
       
   285           ( ( *c3 & mask ) >> bits0 ) ];                        \
       
   286                                                                 \
       
   287         c0 += 4;                                                \
       
   288         c1 += 4;                                                \
       
   289         c2 += 4;                                                \
       
   290         c3 += 4;                                                \
       
   291       }                                                         \
       
   292       break;                                                    \
       
   293     }                                                           \
       
   294     case 7:                                                     \
       
   295     {                                                           \
       
   296       for( j = 0; j < length; j++ )                             \
       
   297       {                                                         \
       
   298         dst[ j ] = table[ ( ( *c0 & mask ) << 20 ) |            \
       
   299           ( ( *c1 & mask ) << 13 ) |                            \
       
   300           ( ( *c2 & mask ) << 6 ) |                             \
       
   301           ( ( *c3 & mask ) >> 1 ) ];                            \
       
   302                                                                 \
       
   303         c0 += 4;                                                \
       
   304         c1 += 4;                                                \
       
   305         c2 += 4;                                                \
       
   306         c3 += 4;                                                \
       
   307       }                                                         \
       
   308       break;                                                    \
       
   309     }                                                           \
       
   310     case 8: /* will never be called */                          \
       
   311     {                                                           \
       
   312       for( j = 0; j < length; j++ )                             \
       
   313       {                                                         \
       
   314         dst[ j ] = table[ ( ( *c0 & mask ) << 24 ) |            \
       
   315           ( ( *c1 & mask ) << 16 ) |                            \
       
   316           ( ( *c2 & mask ) << 8 ) |                             \
       
   317           ( *c3 & mask ) ];                                     \
       
   318                                                                 \
       
   319         c0 += 4;                                                \
       
   320         c1 += 4;                                                \
       
   321         c2 += 4;                                                \
       
   322         c3 += 4;                                                \
       
   323       }                                                         \
       
   324       break;                                                    \
       
   325     }                                                           \
       
   326   }                                                             \
       
   327 }
       
   328 
       
   329 /***************************************************************/
       
   330 #define COLOR_CUBE_S16_3_SEARCH( TABLE_TYPE, SHIFT, STEP )                 \
       
   331 {                                                                          \
       
   332   const mlib_s16 *c0, *c1, *c2;                                            \
       
   333   mlib_s32 bits = s->bits;                                                 \
       
   334   mlib_s32 nbits = 16 - bits;                                              \
       
   335   mlib_s32 mask = ~( ( 1 << nbits ) - 1 );                                 \
       
   336   TABLE_TYPE *table = s->table;                                            \
       
   337   mlib_s32 j;                                                              \
       
   338                                                                            \
       
   339   c0 = src + SHIFT;                                                        \
       
   340   c1 = src + 1 + SHIFT;                                                    \
       
   341   c2 = src + 2 + SHIFT;                                                    \
       
   342                                                                            \
       
   343   switch( bits )                                                           \
       
   344   {                                                                        \
       
   345     case 1:                                                                \
       
   346     case 2:                                                                \
       
   347     case 3:                                                                \
       
   348     case 4:                                                                \
       
   349     case 5:                                                                \
       
   350     {                                                                      \
       
   351       mlib_s32 bits0 = 16 - bits;                                          \
       
   352       mlib_s32 bits1 = bits0 - bits;                                       \
       
   353       mlib_s32 bits2 = bits1 - bits;                                       \
       
   354                                                                            \
       
   355       for( j = 0; j < length; j++ )                                        \
       
   356       {                                                                    \
       
   357         dst[ j ] = table[ ( ( ( *c0 - MLIB_S16_MIN ) & mask ) >> bits2 ) | \
       
   358           ( ( ( *c1 - MLIB_S16_MIN ) & mask ) >> bits1 ) |                 \
       
   359           ( ( ( *c2 - MLIB_S16_MIN ) & mask ) >> bits0 ) ];                \
       
   360                                                                            \
       
   361         c0 += STEP;                                                        \
       
   362         c1 += STEP;                                                        \
       
   363         c2 += STEP;                                                        \
       
   364       }                                                                    \
       
   365       break;                                                               \
       
   366     }                                                                      \
       
   367     case 6:                                                                \
       
   368     case 7:                                                                \
       
   369     {                                                                      \
       
   370       mlib_s32 bits0 = 16 - bits;                                          \
       
   371       mlib_s32 bits1 = bits0 - bits;                                       \
       
   372       mlib_s32 bits2 = bits * 3 - 16;                                      \
       
   373                                                                            \
       
   374       for( j = 0; j < length; j++ )                                        \
       
   375       {                                                                    \
       
   376         dst[ j ] = table[ ( ( ( *c0 - MLIB_S16_MIN ) & mask ) << bits2 ) | \
       
   377           ( ( ( *c1 - MLIB_S16_MIN ) & mask ) >> bits1 ) |                 \
       
   378           ( ( ( *c2 - MLIB_S16_MIN ) & mask ) >> bits0 ) ];                \
       
   379                                                                            \
       
   380         c0 += STEP;                                                        \
       
   381         c1 += STEP;                                                        \
       
   382         c2 += STEP;                                                        \
       
   383       }                                                                    \
       
   384       break;                                                               \
       
   385     }                                                                      \
       
   386     case 8:                                                                \
       
   387     {                                                                      \
       
   388       for( j = 0; j < length; j++ )                                        \
       
   389       {                                                                    \
       
   390         dst[ j ] = table[ ( ( ( *c0 - MLIB_S16_MIN ) & mask ) << 8 ) |     \
       
   391           ( ( *c1 - MLIB_S16_MIN ) & mask ) |                              \
       
   392           ( ( ( *c2 - MLIB_S16_MIN ) & mask ) >> 8 ) ];                    \
       
   393                                                                            \
       
   394         c0 += STEP;                                                        \
       
   395         c1 += STEP;                                                        \
       
   396         c2 += STEP;                                                        \
       
   397       }                                                                    \
       
   398       break;                                                               \
       
   399     }                                                                      \
       
   400     case 9:                                                                \
       
   401     case 10:                                                               \
       
   402     {                                                                      \
       
   403       mlib_s32 bits0 = 16 - bits;                                          \
       
   404       mlib_s32 bits1 = 2 * bits - 16;                                      \
       
   405       mlib_s32 bits2 = bits1 + bits;                                       \
       
   406                                                                            \
       
   407       for( j = 0; j < length; j++ )                                        \
       
   408       {                                                                    \
       
   409         dst[ j ] = table[ ( ( ( *c0 - MLIB_S16_MIN ) & mask ) << bits2 ) | \
       
   410           ( ( ( *c1 - MLIB_S16_MIN ) & mask ) << bits1 ) |                 \
       
   411           ( ( ( *c2 - MLIB_S16_MIN ) & mask ) >> bits0 ) ];                \
       
   412                                                                            \
       
   413         c0 += STEP;                                                        \
       
   414         c1 += STEP;                                                        \
       
   415         c2 += STEP;                                                        \
       
   416       }                                                                    \
       
   417       break;                                                               \
       
   418     }                                                                      \
       
   419     /* Other cases may not be considered as the table size will be more    \
       
   420        than 2^32 */                                                        \
       
   421   }                                                                        \
       
   422 }
       
   423 
       
   424 /***************************************************************/
       
   425 #define COLOR_CUBE_S16_4_SEARCH( TABLE_TYPE )                              \
       
   426 {                                                                          \
       
   427   const mlib_s16 *c0, *c1, *c2, *c3;                                       \
       
   428   TABLE_TYPE *table = s->table;                                            \
       
   429   mlib_s32 bits = s->bits;                                                 \
       
   430   mlib_s32 nbits = 16 - bits;                                              \
       
   431   mlib_s32 mask = ~( ( 1 << nbits ) - 1 );                                 \
       
   432   mlib_s32 j;                                                              \
       
   433                                                                            \
       
   434   c0 = src;                                                                \
       
   435   c1 = src + 1;                                                            \
       
   436   c2 = src + 2;                                                            \
       
   437   c3 = src + 3;                                                            \
       
   438                                                                            \
       
   439   switch( bits )                                                           \
       
   440   {                                                                        \
       
   441     case 1:                                                                \
       
   442     case 2:                                                                \
       
   443     case 3:                                                                \
       
   444     {                                                                      \
       
   445       mlib_s32 bits0 = 16 - bits;                                          \
       
   446       mlib_s32 bits1 = bits0 - bits;                                       \
       
   447       mlib_s32 bits2 = bits1 - bits;                                       \
       
   448       mlib_s32 bits3 = bits2 - bits;                                       \
       
   449                                                                            \
       
   450       for( j = 0; j < length; j++ )                                        \
       
   451       {                                                                    \
       
   452         dst[ j ] = table[ ( ( ( *c0 - MLIB_S16_MIN ) & mask ) >> bits3 ) | \
       
   453           ( ( ( *c1 - MLIB_S16_MIN ) & mask ) >> bits2 ) |                 \
       
   454           ( ( ( *c2 - MLIB_S16_MIN ) & mask ) >> bits1 ) |                 \
       
   455           ( ( ( *c3 - MLIB_S16_MIN ) & mask ) >> bits0 ) ];                \
       
   456                                                                            \
       
   457         c0 += 4;                                                           \
       
   458         c1 += 4;                                                           \
       
   459         c2 += 4;                                                           \
       
   460         c3 += 4;                                                           \
       
   461       }                                                                    \
       
   462       break;                                                               \
       
   463     }                                                                      \
       
   464     case 4:                                                                \
       
   465     {                                                                      \
       
   466       for( j = 0; j < length; j++ )                                        \
       
   467       {                                                                    \
       
   468         dst[ j ] = table[ ( ( *c0 - MLIB_S16_MIN ) & mask ) |              \
       
   469           ( ( ( *c1 - MLIB_S16_MIN ) & mask ) >> 4 ) |                     \
       
   470           ( ( ( *c2 - MLIB_S16_MIN ) & mask ) >> 8 ) |                     \
       
   471           ( ( ( *c3 - MLIB_S16_MIN ) & mask ) >> 12 ) ];                   \
       
   472                                                                            \
       
   473         c0 += 4;                                                           \
       
   474         c1 += 4;                                                           \
       
   475         c2 += 4;                                                           \
       
   476         c3 += 4;                                                           \
       
   477       }                                                                    \
       
   478       break;                                                               \
       
   479     }                                                                      \
       
   480     case 5:                                                                \
       
   481     {                                                                      \
       
   482       for( j = 0; j < length; j++ )                                        \
       
   483       {                                                                    \
       
   484         dst[ j ] = table[ ( ( ( *c0 - MLIB_S16_MIN ) & mask ) << 4 ) |     \
       
   485           ( ( ( *c1 - MLIB_S16_MIN ) & mask ) >> 1 ) |                     \
       
   486           ( ( ( *c2 - MLIB_S16_MIN ) & mask ) >> 6 ) |                     \
       
   487           ( ( ( *c3 - MLIB_S16_MIN ) & mask ) >> 11 ) ];                   \
       
   488                                                                            \
       
   489         c0 += 4;                                                           \
       
   490         c1 += 4;                                                           \
       
   491         c2 += 4;                                                           \
       
   492         c3 += 4;                                                           \
       
   493       }                                                                    \
       
   494       break;                                                               \
       
   495     }                                                                      \
       
   496     case 6:                                                                \
       
   497     case 7:                                                                \
       
   498     {                                                                      \
       
   499       mlib_s32 bits0 = 16 - bits;                                          \
       
   500       mlib_s32 bits1 = bits0 - bits;                                       \
       
   501       mlib_s32 bits3 = bits * 4 - 16;                                      \
       
   502       mlib_s32 bits2 = bits3 - bits;                                       \
       
   503                                                                            \
       
   504       for( j = 0; j < length; j++ )                                        \
       
   505       {                                                                    \
       
   506         dst[ j ] = table[ ( ( ( *c0 - MLIB_S16_MIN ) & mask ) << bits3 ) | \
       
   507           ( ( ( *c1 - MLIB_S16_MIN ) & mask ) << bits2 ) |                 \
       
   508           ( ( ( *c2 - MLIB_S16_MIN ) & mask ) >> bits1 ) |                 \
       
   509           ( ( ( *c3 - MLIB_S16_MIN ) & mask ) >> bits0 ) ];                \
       
   510                                                                            \
       
   511         c0 += 4;                                                           \
       
   512         c1 += 4;                                                           \
       
   513         c2 += 4;                                                           \
       
   514         c3 += 4;                                                           \
       
   515       }                                                                    \
       
   516       break;                                                               \
       
   517     }                                                                      \
       
   518     case 8:                                                                \
       
   519     {                                                                      \
       
   520       for( j = 0; j < length; j++ )                                        \
       
   521       {                                                                    \
       
   522         dst[ j ] = table[ ( ( ( *c0 - MLIB_S16_MIN ) & mask ) << 16 ) |    \
       
   523           ( ( ( *c1 - MLIB_S16_MIN ) & mask ) << 8 ) |                     \
       
   524           ( ( *c2 - MLIB_S16_MIN ) & mask ) |                              \
       
   525           ( ( ( *c3 - MLIB_S16_MIN ) & mask ) >> 8 ) ];                    \
       
   526                                                                            \
       
   527         c0 += 4;                                                           \
       
   528         c1 += 4;                                                           \
       
   529         c2 += 4;                                                           \
       
   530         c3 += 4;                                                           \
       
   531       }                                                                    \
       
   532       break;                                                               \
       
   533     }                                                                      \
       
   534     /* Other cases may not be considered as the table size will be more    \
       
   535        than 2^32 */                                                        \
       
   536   }                                                                        \
       
   537 }
       
   538 
       
   539 /***************************************************************/
       
   540 #define BINARY_TREE_SEARCH_RIGHT( POSITION, COLOR_MAX, SHIFT )  \
       
   541 {                                                               \
       
   542   if( ( distance >= ( ( ( position[ POSITION ] + current_size - \
       
   543     c[ POSITION ] ) * ( position[ POSITION ] + current_size -   \
       
   544     c[ POSITION ] ) ) >> SHIFT ) ) &&                           \
       
   545     ( position[ POSITION ] + current_size != COLOR_MAX ) )      \
       
   546     continue_up = 1;                                            \
       
   547 }
       
   548 
       
   549 /***************************************************************/
       
   550 #define BINARY_TREE_EXPLORE_RIGHT_3( POSITION, COLOR_MAX, IMAGE_TYPE,    \
       
   551   FIRST_NEIBOUR, SECOND_NEIBOUR, SUBSTRACTION, SHIFT )                   \
       
   552 {                                                                        \
       
   553   if( distance >= ( ( ( position[ POSITION ] + current_size -            \
       
   554     c[ POSITION ] ) * ( position[ POSITION ] +                           \
       
   555       current_size - c[ POSITION ] ) ) >> SHIFT ) )                      \
       
   556   {                                                                      \
       
   557     if( distance < ( ( ( COLOR_MAX - c[ POSITION ] ) *                   \
       
   558       ( COLOR_MAX - c[ POSITION ] ) ) >> SHIFT ) )                       \
       
   559     {                                                                    \
       
   560       if( distance < ( ( ( position[ POSITION ] +                        \
       
   561         current_size * 2 - c[ POSITION ] ) *                             \
       
   562         ( position[ POSITION ] + current_size * 2 -                      \
       
   563           c[ POSITION ] ) ) >> SHIFT ) )                                 \
       
   564       {                                                                  \
       
   565         /* Check only a part of quadrant */                              \
       
   566         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
   567                                                                          \
       
   568         check_neibours[ FIRST_NEIBOUR ] += 1;                            \
       
   569         check_neibours[ SECOND_NEIBOUR ] += 1;                           \
       
   570         check_corner += 1;                                               \
       
   571         if( node->tag & ( 1 << qq ) )                                    \
       
   572         {                                                                \
       
   573           /* Here is another color cell.                                 \
       
   574              Check the distance */                                       \
       
   575           mlib_s32 new_found_color =                                     \
       
   576             node->contents.index[ qq ];                                  \
       
   577           mlib_u32 newdistance = FIND_DISTANCE_3( c[ 0 ],                \
       
   578             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
   579             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
   580             p[ 2 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
   581                                                                          \
       
   582           if( newdistance < distance )                                   \
       
   583           {                                                              \
       
   584             found_color = new_found_color;                               \
       
   585             distance = newdistance;                                      \
       
   586           }                                                              \
       
   587         }                                                                \
       
   588         else if( node->contents.quadrants[ qq ] )                        \
       
   589           /* Only a part of quadrant needs checking */                   \
       
   590           distance =                                                     \
       
   591             mlib_search_quadrant_part_to_left_##IMAGE_TYPE##_3(          \
       
   592               node->contents.quadrants[ qq ],                            \
       
   593               distance, &found_color, c, p,                              \
       
   594               position[ POSITION ] + current_size, pass - 1, POSITION ); \
       
   595       }                                                                  \
       
   596       else /* Check whole quadrant */                                    \
       
   597       {                                                                  \
       
   598         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
   599                                                                          \
       
   600         check_neibours[ FIRST_NEIBOUR ] += 2;                            \
       
   601         check_neibours[ SECOND_NEIBOUR ] += 2;                           \
       
   602         check_corner += 2;                                               \
       
   603         continue_up = 1;                                                 \
       
   604         if( node->tag & ( 1 << qq ) )                                    \
       
   605         {                                                                \
       
   606           /* Here is another color cell.                                 \
       
   607              Check the distance */                                       \
       
   608           mlib_s32 new_found_color =                                     \
       
   609             node->contents.index[ qq ];                                  \
       
   610           mlib_u32 newdistance = FIND_DISTANCE_3( c[ 0 ],                \
       
   611             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
   612             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
   613             p[ 2 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
   614                                                                          \
       
   615           if( newdistance < distance )                                   \
       
   616           {                                                              \
       
   617             found_color = new_found_color;                               \
       
   618             distance = newdistance;                                      \
       
   619           }                                                              \
       
   620         }                                                                \
       
   621         else if( node->contents.quadrants[ qq ] )                        \
       
   622           /* Here is a full node. Just explore it */                     \
       
   623           distance = mlib_search_quadrant_##IMAGE_TYPE##_3(              \
       
   624             node->contents.quadrants[ qq ],                              \
       
   625             distance, &found_color, c[ 0 ], c[ 1 ], c[ 2 ], p );         \
       
   626       }                                                                  \
       
   627     }                                                                    \
       
   628     else /* Cell is on the edge of the space */                          \
       
   629     {                                                                    \
       
   630       if( position[ POSITION ] + current_size * 2 ==                     \
       
   631         COLOR_MAX )                                                      \
       
   632       {                                                                  \
       
   633         /* Check only a part of quadrant */                              \
       
   634         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
   635                                                                          \
       
   636         check_neibours[ FIRST_NEIBOUR ] += 1;                            \
       
   637         check_neibours[ SECOND_NEIBOUR ] += 1;                           \
       
   638         check_corner += 1;                                               \
       
   639         if( node->tag & ( 1 << qq ) )                                    \
       
   640         {                                                                \
       
   641           /* Here is another color cell.                                 \
       
   642              Check the distance */                                       \
       
   643           mlib_s32 new_found_color =                                     \
       
   644             node->contents.index[ qq ];                                  \
       
   645           mlib_u32 newdistance = FIND_DISTANCE_3( c[ 0 ],                \
       
   646             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
   647             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
   648             p[ 2 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
   649                                                                          \
       
   650           if( newdistance < distance )                                   \
       
   651           {                                                              \
       
   652             found_color = new_found_color;                               \
       
   653             distance = newdistance;                                      \
       
   654           }                                                              \
       
   655         }                                                                \
       
   656         else if( node->contents.quadrants[ qq ] )                        \
       
   657           /* Only a part of quadrant needs checking */                   \
       
   658           distance =                                                     \
       
   659             mlib_search_quadrant_part_to_left_##IMAGE_TYPE##_3(          \
       
   660               node->contents.quadrants[ qq ],                            \
       
   661               distance, &found_color, c, p,                              \
       
   662               position[ POSITION ] + current_size,                       \
       
   663               pass - 1, POSITION );                                      \
       
   664       }                                                                  \
       
   665       else /* Check whole quadrant */                                    \
       
   666       {                                                                  \
       
   667         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
   668                                                                          \
       
   669         check_neibours[ FIRST_NEIBOUR ] += 2;                            \
       
   670         check_neibours[ SECOND_NEIBOUR ] += 2;                           \
       
   671         check_corner += 2;                                               \
       
   672         continue_up = 1;                                                 \
       
   673         if( node->tag & ( 1 << qq ) )                                    \
       
   674         {                                                                \
       
   675           /* Here is another color cell.                                 \
       
   676              Check the distance */                                       \
       
   677           mlib_s32 new_found_color =                                     \
       
   678             node->contents.index[ qq ];                                  \
       
   679           mlib_u32 newdistance = FIND_DISTANCE_3( c[ 0 ],                \
       
   680             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
   681             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
   682             p[ 2 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
   683                                                                          \
       
   684           if( newdistance < distance )                                   \
       
   685           {                                                              \
       
   686             found_color = new_found_color;                               \
       
   687             distance = newdistance;                                      \
       
   688           }                                                              \
       
   689         }                                                                \
       
   690         else if( node->contents.quadrants[ qq ] )                        \
       
   691           /* Here is a full node. Just explore it */                     \
       
   692           distance = mlib_search_quadrant_##IMAGE_TYPE##_3(              \
       
   693             node->contents.quadrants[ qq ],                              \
       
   694             distance, &found_color, c[ 0 ], c[ 1 ], c[ 2 ], p );         \
       
   695       }                                                                  \
       
   696     }                                                                    \
       
   697   }                                                                      \
       
   698 }
       
   699 
       
   700 /***************************************************************/
       
   701 #define BINARY_TREE_EXPLORE_RIGHT_4( POSITION, COLOR_MAX, IMAGE_TYPE,    \
       
   702   FIRST_NEIBOUR, SECOND_NEIBOUR, THIRD_NEIBOUR, SUBSTRACTION, SHIFT )    \
       
   703 {                                                                        \
       
   704   if( distance >= ( ( ( position[ POSITION ] + current_size -            \
       
   705     c[ POSITION ] ) * ( position[ POSITION ] +                           \
       
   706       current_size - c[ POSITION ] ) ) >> SHIFT ) )                      \
       
   707   {                                                                      \
       
   708     if( distance < ( ( ( COLOR_MAX - c[ POSITION ] ) *                   \
       
   709       ( COLOR_MAX - c[ POSITION ] ) ) >> SHIFT ) )                       \
       
   710     {                                                                    \
       
   711       if( distance < ( ( ( position[ POSITION ] +                        \
       
   712         current_size * 2 - c[ POSITION ] ) *                             \
       
   713         ( position[ POSITION ] + current_size * 2 -                      \
       
   714           c[ POSITION ] ) ) >> SHIFT ) )                                 \
       
   715       {                                                                  \
       
   716         /* Check only a part of quadrant */                              \
       
   717         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
   718                                                                          \
       
   719         check_neibours[ FIRST_NEIBOUR ] += 1;                            \
       
   720         check_neibours[ SECOND_NEIBOUR ] += 1;                           \
       
   721         check_neibours[ THIRD_NEIBOUR ] += 1;                            \
       
   722         if( node->tag & ( 1 << qq ) )                                    \
       
   723         {                                                                \
       
   724           /* Here is another color cell.                                 \
       
   725              Check the distance */                                       \
       
   726           mlib_s32 new_found_color =                                     \
       
   727             node->contents.index[ qq ];                                  \
       
   728           mlib_u32 newdistance = FIND_DISTANCE_4( c[ 0 ],                \
       
   729             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
   730             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
   731             p[ 2 ][ new_found_color ] - SUBSTRACTION, c[ 3 ],            \
       
   732             p[ 3 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
   733                                                                          \
       
   734           if( newdistance < distance )                                   \
       
   735           {                                                              \
       
   736             found_color = new_found_color;                               \
       
   737             distance = newdistance;                                      \
       
   738           }                                                              \
       
   739         }                                                                \
       
   740         else if( node->contents.quadrants[ qq ] )                        \
       
   741           /* Only a part of quadrant needs checking */                   \
       
   742           distance =                                                     \
       
   743             mlib_search_quadrant_part_to_left_##IMAGE_TYPE##_4(          \
       
   744               node->contents.quadrants[ qq ],                            \
       
   745               distance, &found_color, c, p,                              \
       
   746               position[ POSITION ] + current_size, pass - 1, POSITION ); \
       
   747       }                                                                  \
       
   748       else /* Check whole quadrant */                                    \
       
   749       {                                                                  \
       
   750         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
   751                                                                          \
       
   752         check_neibours[ FIRST_NEIBOUR ] += 2;                            \
       
   753         check_neibours[ SECOND_NEIBOUR ] += 2;                           \
       
   754         check_neibours[ THIRD_NEIBOUR ] += 2;                            \
       
   755         continue_up = 1;                                                 \
       
   756         if( node->tag & ( 1 << qq ) )                                    \
       
   757         {                                                                \
       
   758           /* Here is another color cell.                                 \
       
   759              Check the distance */                                       \
       
   760           mlib_s32 new_found_color =                                     \
       
   761             node->contents.index[ qq ];                                  \
       
   762           mlib_u32 newdistance = FIND_DISTANCE_4( c[ 0 ],                \
       
   763             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
   764             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
   765             p[ 2 ][ new_found_color ] - SUBSTRACTION, c[ 3 ],            \
       
   766             p[ 3 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
   767                                                                          \
       
   768           if( newdistance < distance )                                   \
       
   769           {                                                              \
       
   770             found_color = new_found_color;                               \
       
   771             distance = newdistance;                                      \
       
   772           }                                                              \
       
   773         }                                                                \
       
   774         else if( node->contents.quadrants[ qq ] )                        \
       
   775           /* Here is a full node. Just explore it */                     \
       
   776           distance = mlib_search_quadrant_##IMAGE_TYPE##_4(              \
       
   777             node->contents.quadrants[ qq ],                              \
       
   778             distance, &found_color, c[ 0 ], c[ 1 ], c[ 2 ], c[ 3 ], p ); \
       
   779       }                                                                  \
       
   780     }                                                                    \
       
   781     else /* Cell is on the edge of the space */                          \
       
   782     {                                                                    \
       
   783       if( position[ POSITION ] + current_size * 2 ==                     \
       
   784         COLOR_MAX )                                                      \
       
   785       {                                                                  \
       
   786         /* Check only a part of quadrant */                              \
       
   787         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
   788                                                                          \
       
   789         check_neibours[ FIRST_NEIBOUR ] += 1;                            \
       
   790         check_neibours[ SECOND_NEIBOUR ] += 1;                           \
       
   791         check_neibours[ THIRD_NEIBOUR ] += 1;                            \
       
   792         if( node->tag & ( 1 << qq ) )                                    \
       
   793         {                                                                \
       
   794           /* Here is another color cell.                                 \
       
   795              Check the distance */                                       \
       
   796           mlib_s32 new_found_color =                                     \
       
   797             node->contents.index[ qq ];                                  \
       
   798           mlib_u32 newdistance = FIND_DISTANCE_4( c[ 0 ],                \
       
   799             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
   800             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
   801             p[ 2 ][ new_found_color ] - SUBSTRACTION, c[ 3 ],            \
       
   802             p[ 3 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
   803                                                                          \
       
   804           if( newdistance < distance )                                   \
       
   805           {                                                              \
       
   806             found_color = new_found_color;                               \
       
   807             distance = newdistance;                                      \
       
   808           }                                                              \
       
   809         }                                                                \
       
   810         else if( node->contents.quadrants[ qq ] )                        \
       
   811           /* Only a part of quadrant needs checking */                   \
       
   812           distance =                                                     \
       
   813             mlib_search_quadrant_part_to_left_##IMAGE_TYPE##_4(          \
       
   814               node->contents.quadrants[ qq ],                            \
       
   815               distance, &found_color, c, p,                              \
       
   816               position[ POSITION ] + current_size,                       \
       
   817               pass - 1, POSITION );                                      \
       
   818       }                                                                  \
       
   819       else /* Check whole quadrant */                                    \
       
   820       {                                                                  \
       
   821         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
   822                                                                          \
       
   823         check_neibours[ FIRST_NEIBOUR ] += 2;                            \
       
   824         check_neibours[ SECOND_NEIBOUR ] += 2;                           \
       
   825         check_neibours[ THIRD_NEIBOUR ] += 2;                            \
       
   826         continue_up = 1;                                                 \
       
   827         if( node->tag & ( 1 << qq ) )                                    \
       
   828         {                                                                \
       
   829           /* Here is another color cell.                                 \
       
   830              Check the distance */                                       \
       
   831           mlib_s32 new_found_color =                                     \
       
   832             node->contents.index[ qq ];                                  \
       
   833           mlib_u32 newdistance = FIND_DISTANCE_4( c[ 0 ],                \
       
   834             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
   835             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
   836             p[ 2 ][ new_found_color ] - SUBSTRACTION, c[ 3 ],            \
       
   837             p[ 3 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
   838                                                                          \
       
   839           if( newdistance < distance )                                   \
       
   840           {                                                              \
       
   841             found_color = new_found_color;                               \
       
   842             distance = newdistance;                                      \
       
   843           }                                                              \
       
   844         }                                                                \
       
   845         else if( node->contents.quadrants[ qq ] )                        \
       
   846           /* Here is a full node. Just explore it */                     \
       
   847           distance = mlib_search_quadrant_##IMAGE_TYPE##_4(              \
       
   848             node->contents.quadrants[ qq ],                              \
       
   849             distance, &found_color, c[ 0 ], c[ 1 ], c[ 2 ], c[ 3 ], p ); \
       
   850       }                                                                  \
       
   851     }                                                                    \
       
   852   }                                                                      \
       
   853 }
       
   854 
       
   855 /***************************************************************/
       
   856 #define BINARY_TREE_SEARCH_LEFT( POSITION, SHIFT )                \
       
   857 {                                                                 \
       
   858   if( ( distance > ( ( ( position[ POSITION ] - c[ POSITION ] ) * \
       
   859     ( position[ POSITION ] - c[ POSITION ] ) ) >> SHIFT ) )  &&   \
       
   860     position[ POSITION ] )                                        \
       
   861     continue_up = 1;                                              \
       
   862 }
       
   863 
       
   864 /***************************************************************/
       
   865 #define BINARY_TREE_EXPLORE_LEFT_3( POSITION, IMAGE_TYPE,                \
       
   866   FIRST_NEIBOUR, SECOND_NEIBOUR, SUBSTRACTION, SHIFT )                   \
       
   867 {                                                                        \
       
   868   if( distance >                                                         \
       
   869     ( ( ( c[ POSITION ] - position[ POSITION ] ) *                       \
       
   870     ( c[ POSITION ] - position[ POSITION ] ) ) >> SHIFT ) )              \
       
   871   {                                                                      \
       
   872     if( distance <= ( ( c[ POSITION ] * c[ POSITION ] ) >> SHIFT ) )     \
       
   873     {                                                                    \
       
   874       if( distance <= ( ( ( c[ POSITION ] + current_size -               \
       
   875         position[ POSITION ] ) *                                         \
       
   876         ( c[ POSITION ] + current_size -                                 \
       
   877           position[ POSITION ] ) ) >> SHIFT ) )                          \
       
   878       {                                                                  \
       
   879         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
   880                                                                          \
       
   881         check_neibours[ FIRST_NEIBOUR ] += 1;                            \
       
   882         check_neibours[ SECOND_NEIBOUR ] += 1;                           \
       
   883         check_corner += 1;                                               \
       
   884         if( node->tag & ( 1 << qq ) )                                    \
       
   885         {                                                                \
       
   886           /* Here is another color cell.                                 \
       
   887              Check the distance */                                       \
       
   888           mlib_s32 new_found_color =                                     \
       
   889             node->contents.index[ qq ];                                  \
       
   890           mlib_u32 newdistance = FIND_DISTANCE_3( c[ 0 ],                \
       
   891             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
   892             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
   893             p[ 2 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
   894                                                                          \
       
   895           if( newdistance < distance )                                   \
       
   896           {                                                              \
       
   897             found_color = new_found_color;                               \
       
   898             distance = newdistance;                                      \
       
   899           }                                                              \
       
   900         }                                                                \
       
   901         else if( node->contents.quadrants[ qq ] )                        \
       
   902           /* Only a part of quadrant needs checking */                   \
       
   903           distance =                                                     \
       
   904             mlib_search_quadrant_part_to_right_##IMAGE_TYPE##_3(         \
       
   905               node->contents.quadrants[ qq ],                            \
       
   906               distance, &found_color, c, p,                              \
       
   907               position[ POSITION ] - current_size, pass - 1, POSITION ); \
       
   908       }                                                                  \
       
   909       else /* Check whole quadrant */                                    \
       
   910       {                                                                  \
       
   911         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
   912                                                                          \
       
   913         check_neibours[ FIRST_NEIBOUR ] += 2;                            \
       
   914         check_neibours[ SECOND_NEIBOUR ] += 2;                           \
       
   915         check_corner += 2;                                               \
       
   916         continue_up = 1;                                                 \
       
   917         if( node->tag & ( 1 << qq ) )                                    \
       
   918         {                                                                \
       
   919           /* Here is another color cell.                                 \
       
   920              Check the distance */                                       \
       
   921           mlib_s32 new_found_color =                                     \
       
   922             node->contents.index[ qq ];                                  \
       
   923           mlib_u32 newdistance = FIND_DISTANCE_3( c[ 0 ],                \
       
   924             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
   925             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
   926             p[ 2 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
   927                                                                          \
       
   928           if( newdistance < distance )                                   \
       
   929           {                                                              \
       
   930             found_color = new_found_color;                               \
       
   931             distance = newdistance;                                      \
       
   932           }                                                              \
       
   933         }                                                                \
       
   934         else if( node->contents.quadrants[ qq ] )                        \
       
   935           /* Here is a full node. Just explore it */                     \
       
   936           distance = mlib_search_quadrant_##IMAGE_TYPE##_3(              \
       
   937             node->contents.quadrants[ qq ],                              \
       
   938             distance, &found_color, c[ 0 ], c[ 1 ], c[ 2 ], p );         \
       
   939       }                                                                  \
       
   940     }                                                                    \
       
   941     else                                                                 \
       
   942     {                                                                    \
       
   943       if( !( position[ POSITION ] - current_size ) )                     \
       
   944       {                                                                  \
       
   945         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
   946                                                                          \
       
   947         check_neibours[ FIRST_NEIBOUR ] += 1;                            \
       
   948         check_neibours[ SECOND_NEIBOUR ] += 1;                           \
       
   949         check_corner += 1;                                               \
       
   950         if( node->tag & ( 1 << qq ) )                                    \
       
   951         {                                                                \
       
   952           /* Here is another color cell.                                 \
       
   953              Check the distance */                                       \
       
   954           mlib_s32 new_found_color =                                     \
       
   955             node->contents.index[ qq ];                                  \
       
   956           mlib_u32 newdistance = FIND_DISTANCE_3( c[ 0 ],                \
       
   957             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
   958             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
   959             p[ 2 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
   960                                                                          \
       
   961           if( newdistance < distance )                                   \
       
   962           {                                                              \
       
   963             found_color = new_found_color;                               \
       
   964             distance = newdistance;                                      \
       
   965           }                                                              \
       
   966         }                                                                \
       
   967         else if( node->contents.quadrants[ qq ] )                        \
       
   968           /* Only a part of quadrant needs checking */                   \
       
   969           distance =                                                     \
       
   970             mlib_search_quadrant_part_to_right_##IMAGE_TYPE##_3(         \
       
   971               node->contents.quadrants[ qq ],                            \
       
   972               distance, &found_color, c, p,                              \
       
   973               position[ POSITION ] - current_size, pass - 1, POSITION ); \
       
   974       }                                                                  \
       
   975       else                                                               \
       
   976       {                                                                  \
       
   977         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
   978                                                                          \
       
   979         check_neibours[ FIRST_NEIBOUR ] += 2;                            \
       
   980         check_neibours[ SECOND_NEIBOUR ] += 2;                           \
       
   981         check_corner += 2;                                               \
       
   982         continue_up = 1;                                                 \
       
   983         if( node->tag & ( 1 << qq ) )                                    \
       
   984         {                                                                \
       
   985           /* Here is another color cell.                                 \
       
   986              Check the distance */                                       \
       
   987           mlib_s32 new_found_color =                                     \
       
   988             node->contents.index[ qq ];                                  \
       
   989           mlib_u32 newdistance = FIND_DISTANCE_3( c[ 0 ],                \
       
   990             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
   991             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
   992             p[ 2 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
   993                                                                          \
       
   994           if( newdistance < distance )                                   \
       
   995           {                                                              \
       
   996             found_color = new_found_color;                               \
       
   997             distance = newdistance;                                      \
       
   998           }                                                              \
       
   999         }                                                                \
       
  1000         else if( node->contents.quadrants[ qq ] )                        \
       
  1001           /* Here is a full node. Just explore it */                     \
       
  1002           distance = mlib_search_quadrant_##IMAGE_TYPE##_3(              \
       
  1003             node->contents.quadrants[ qq ],                              \
       
  1004             distance, &found_color, c[ 0 ], c[ 1 ], c[ 2 ], p );         \
       
  1005       }                                                                  \
       
  1006     }                                                                    \
       
  1007   }                                                                      \
       
  1008 }
       
  1009 
       
  1010 /***************************************************************/
       
  1011 #define BINARY_TREE_EXPLORE_LEFT_4( POSITION, IMAGE_TYPE,                \
       
  1012   FIRST_NEIBOUR, SECOND_NEIBOUR, THIRD_NEIBOUR, SUBSTRACTION, SHIFT )    \
       
  1013 {                                                                        \
       
  1014   if( distance >                                                         \
       
  1015     ( ( ( c[ POSITION ] - position[ POSITION ] ) *                       \
       
  1016     ( c[ POSITION ] - position[ POSITION ] ) ) >> SHIFT ) )              \
       
  1017   {                                                                      \
       
  1018     if( distance <= ( ( c[ POSITION ] * c[ POSITION ] ) >> SHIFT ) )     \
       
  1019     {                                                                    \
       
  1020       if( distance <= ( ( ( c[ POSITION ] + current_size -               \
       
  1021         position[ POSITION ] ) *                                         \
       
  1022         ( c[ POSITION ] + current_size -                                 \
       
  1023           position[ POSITION ] ) ) >> SHIFT ) )                          \
       
  1024       {                                                                  \
       
  1025         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
  1026                                                                          \
       
  1027         check_neibours[ FIRST_NEIBOUR ] += 1;                            \
       
  1028         check_neibours[ SECOND_NEIBOUR ] += 1;                           \
       
  1029         check_neibours[ THIRD_NEIBOUR ] += 1;                            \
       
  1030         if( node->tag & ( 1 << qq ) )                                    \
       
  1031         {                                                                \
       
  1032           /* Here is another color cell.                                 \
       
  1033              Check the distance */                                       \
       
  1034           mlib_s32 new_found_color =                                     \
       
  1035             node->contents.index[ qq ];                                  \
       
  1036           mlib_u32 newdistance = FIND_DISTANCE_4( c[ 0 ],                \
       
  1037             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
  1038             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
  1039             p[ 2 ][ new_found_color ] - SUBSTRACTION, c[ 3 ],            \
       
  1040             p[ 3 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
  1041                                                                          \
       
  1042           if( newdistance < distance )                                   \
       
  1043           {                                                              \
       
  1044             found_color = new_found_color;                               \
       
  1045             distance = newdistance;                                      \
       
  1046           }                                                              \
       
  1047         }                                                                \
       
  1048         else if( node->contents.quadrants[ qq ] )                        \
       
  1049           /* Only a part of quadrant needs checking */                   \
       
  1050           distance =                                                     \
       
  1051             mlib_search_quadrant_part_to_right_##IMAGE_TYPE##_4(         \
       
  1052               node->contents.quadrants[ qq ],                            \
       
  1053               distance, &found_color, c, p,                              \
       
  1054               position[ POSITION ] - current_size, pass - 1, POSITION ); \
       
  1055       }                                                                  \
       
  1056       else /* Check whole quadrant */                                    \
       
  1057       {                                                                  \
       
  1058         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
  1059                                                                          \
       
  1060         check_neibours[ FIRST_NEIBOUR ] += 2;                            \
       
  1061         check_neibours[ SECOND_NEIBOUR ] += 2;                           \
       
  1062         check_neibours[ THIRD_NEIBOUR ] += 2;                            \
       
  1063         continue_up = 1;                                                 \
       
  1064         if( node->tag & ( 1 << qq ) )                                    \
       
  1065         {                                                                \
       
  1066           /* Here is another color cell.                                 \
       
  1067              Check the distance */                                       \
       
  1068           mlib_s32 new_found_color =                                     \
       
  1069             node->contents.index[ qq ];                                  \
       
  1070           mlib_u32 newdistance = FIND_DISTANCE_4( c[ 0 ],                \
       
  1071             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
  1072             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
  1073             p[ 2 ][ new_found_color ] - SUBSTRACTION, c[ 3 ],            \
       
  1074             p[ 3 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
  1075                                                                          \
       
  1076           if( newdistance < distance )                                   \
       
  1077           {                                                              \
       
  1078             found_color = new_found_color;                               \
       
  1079             distance = newdistance;                                      \
       
  1080           }                                                              \
       
  1081         }                                                                \
       
  1082         else if( node->contents.quadrants[ qq ] )                        \
       
  1083           /* Here is a full node. Just explore it */                     \
       
  1084           distance = mlib_search_quadrant_##IMAGE_TYPE##_4(              \
       
  1085             node->contents.quadrants[ qq ],                              \
       
  1086             distance, &found_color, c[ 0 ], c[ 1 ], c[ 2 ], c[ 3 ], p ); \
       
  1087       }                                                                  \
       
  1088     }                                                                    \
       
  1089     else                                                                 \
       
  1090     {                                                                    \
       
  1091       if( !( position[ POSITION ] - current_size ) )                     \
       
  1092       {                                                                  \
       
  1093         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
  1094                                                                          \
       
  1095         check_neibours[ FIRST_NEIBOUR ] += 1;                            \
       
  1096         check_neibours[ SECOND_NEIBOUR ] += 1;                           \
       
  1097         check_neibours[ THIRD_NEIBOUR ] += 1;                            \
       
  1098         if( node->tag & ( 1 << qq ) )                                    \
       
  1099         {                                                                \
       
  1100           /* Here is another color cell.                                 \
       
  1101              Check the distance */                                       \
       
  1102           mlib_s32 new_found_color =                                     \
       
  1103             node->contents.index[ qq ];                                  \
       
  1104           mlib_u32 newdistance = FIND_DISTANCE_4( c[ 0 ],                \
       
  1105             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
  1106             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
  1107             p[ 2 ][ new_found_color ] - SUBSTRACTION, c[ 3 ],            \
       
  1108             p[ 3 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
  1109                                                                          \
       
  1110           if( newdistance < distance )                                   \
       
  1111           {                                                              \
       
  1112             found_color = new_found_color;                               \
       
  1113             distance = newdistance;                                      \
       
  1114           }                                                              \
       
  1115         }                                                                \
       
  1116         else if( node->contents.quadrants[ qq ] )                        \
       
  1117           /* Only a part of quadrant needs checking */                   \
       
  1118           distance =                                                     \
       
  1119             mlib_search_quadrant_part_to_right_##IMAGE_TYPE##_4(         \
       
  1120               node->contents.quadrants[ qq ],                            \
       
  1121               distance, &found_color, c, p,                              \
       
  1122               position[ POSITION ] - current_size, pass - 1, POSITION ); \
       
  1123       }                                                                  \
       
  1124       else                                                               \
       
  1125       {                                                                  \
       
  1126         mlib_s32 qq = q ^ ( 1 << POSITION );                             \
       
  1127                                                                          \
       
  1128         check_neibours[ FIRST_NEIBOUR ] += 2;                            \
       
  1129         check_neibours[ SECOND_NEIBOUR ] += 2;                           \
       
  1130         check_neibours[ THIRD_NEIBOUR ] += 2;                            \
       
  1131         continue_up = 1;                                                 \
       
  1132         if( node->tag & ( 1 << qq ) )                                    \
       
  1133         {                                                                \
       
  1134           /* Here is another color cell.                                 \
       
  1135              Check the distance */                                       \
       
  1136           mlib_s32 new_found_color =                                     \
       
  1137             node->contents.index[ qq ];                                  \
       
  1138           mlib_u32 newdistance = FIND_DISTANCE_4( c[ 0 ],                \
       
  1139             p[ 0 ][ new_found_color ] - SUBSTRACTION, c[ 1 ],            \
       
  1140             p[ 1 ][ new_found_color ] - SUBSTRACTION, c[ 2 ],            \
       
  1141             p[ 2 ][ new_found_color ] - SUBSTRACTION, c[ 3 ],            \
       
  1142             p[ 3 ][ new_found_color ] - SUBSTRACTION, SHIFT );           \
       
  1143                                                                          \
       
  1144           if( newdistance < distance )                                   \
       
  1145           {                                                              \
       
  1146             found_color = new_found_color;                               \
       
  1147             distance = newdistance;                                      \
       
  1148           }                                                              \
       
  1149         }                                                                \
       
  1150         else if( node->contents.quadrants[ qq ] )                        \
       
  1151           /* Here is a full node. Just explore it */                     \
       
  1152           distance = mlib_search_quadrant_##IMAGE_TYPE##_4(              \
       
  1153             node->contents.quadrants[ qq ],                              \
       
  1154             distance, &found_color, c[ 0 ], c[ 1 ], c[ 2 ], c[ 3 ], p ); \
       
  1155       }                                                                  \
       
  1156     }                                                                    \
       
  1157   }                                                                      \
       
  1158 }
       
  1159 
       
  1160 /***************************************************************/
       
  1161 #define CHECK_QUADRANT_U8_3( qq )                               \
       
  1162 {                                                               \
       
  1163   if( node->tag & ( 1 << qq ) )                                 \
       
  1164   {                                                             \
       
  1165     /* Here is another color cell. Check the distance */        \
       
  1166     mlib_s32 new_found_color = node->contents.index[ qq ];      \
       
  1167     mlib_u32 newdistance = FIND_DISTANCE_3( c[ 0 ],             \
       
  1168       p[ 0 ][ new_found_color ], c[ 1 ],                        \
       
  1169       p[ 1 ][ new_found_color ], c[ 2 ],                        \
       
  1170       p[ 2 ][ new_found_color ], 0 );                           \
       
  1171                                                                 \
       
  1172     if( newdistance < distance )                                \
       
  1173     {                                                           \
       
  1174       found_color = new_found_color;                            \
       
  1175       distance = newdistance;                                   \
       
  1176     }                                                           \
       
  1177   }                                                             \
       
  1178   else if( node->contents.quadrants[ qq ] )                     \
       
  1179     /* Here is a full node. Just explore it all */              \
       
  1180     distance = mlib_search_quadrant_U8_3(                       \
       
  1181       node->contents.quadrants[ qq ], distance, &found_color,   \
       
  1182       c[ 0 ], c[ 1 ], c[ 2 ], p );                              \
       
  1183 /* Else there is just an empty cell */                          \
       
  1184 }
       
  1185 
       
  1186 /***************************************************************/
       
  1187 #define CHECK_QUADRANT_S16_3( qq )                              \
       
  1188 {                                                               \
       
  1189   if( node->tag & ( 1 << qq ) )                                 \
       
  1190   {                                                             \
       
  1191     /* Here is another color cell. Check the distance */        \
       
  1192     mlib_s32 new_found_color = node->contents.index[ qq ];      \
       
  1193     mlib_u32 palc0, palc1, palc2, newdistance;                  \
       
  1194                                                                 \
       
  1195     palc0 = p[ 0 ][ new_found_color ] - MLIB_S16_MIN;           \
       
  1196     palc1 = p[ 1 ][ new_found_color ] - MLIB_S16_MIN;           \
       
  1197     palc2 = p[ 2 ][ new_found_color ] - MLIB_S16_MIN;           \
       
  1198                                                                 \
       
  1199     newdistance = FIND_DISTANCE_3( c[ 0 ], palc0,               \
       
  1200       c[ 1 ], palc1,                                            \
       
  1201       c[ 2 ], palc2, 2 );                                       \
       
  1202                                                                 \
       
  1203     if( newdistance < distance )                                \
       
  1204     {                                                           \
       
  1205       found_color = new_found_color;                            \
       
  1206       distance = newdistance;                                   \
       
  1207     }                                                           \
       
  1208   }                                                             \
       
  1209   else if( node->contents.quadrants[ qq ] )                     \
       
  1210     /* Here is a full node. Just explore it all */              \
       
  1211     distance = mlib_search_quadrant_S16_3(                      \
       
  1212       node->contents.quadrants[ qq ], distance, &found_color,   \
       
  1213       c[ 0 ], c[ 1 ], c[ 2 ], p );                              \
       
  1214 /* Else there is just an empty cell */                          \
       
  1215 }
       
  1216 
       
  1217 /***************************************************************/
       
  1218 #define BINARY_TREE_SEARCH_3( SOURCE_IMAGE, POINTER_TYPE, BITS,              \
       
  1219   COLOR_MAX, SUBTRACTION, POINTER_SHIFT, STEP, SHIFT )                       \
       
  1220 {                                                                            \
       
  1221   const POINTER_TYPE *channels[ 3 ], *p[ 3 ];                                \
       
  1222   mlib_u32 c[ 3 ];                                                           \
       
  1223   mlib_s32 j;                                                                \
       
  1224                                                                              \
       
  1225   p[ 0 ] = s->lut[ 0 ];                                                      \
       
  1226   p[ 1 ] = s->lut[ 1 ];                                                      \
       
  1227   p[ 2 ] = s->lut[ 2 ];                                                      \
       
  1228   channels[ 0 ] = src + POINTER_SHIFT;                                       \
       
  1229   channels[ 1 ] = src + 1 + POINTER_SHIFT;                                   \
       
  1230   channels[ 2 ] = src + 2 + POINTER_SHIFT;                                   \
       
  1231                                                                              \
       
  1232   for( j = 0; j < length; j++ )                                              \
       
  1233   {                                                                          \
       
  1234     mlib_s32 pass = BITS - 1;                                                \
       
  1235     mlib_u32 position[ 3 ] = { 0, 0, 0 };                                    \
       
  1236     mlib_s32 we_found_it = 0;                                                \
       
  1237     struct lut_node_3 *node = s->table;                                      \
       
  1238     /* Stack pointer pointers to the first free element of stack. */         \
       
  1239     /* The node we are in is in the `node' */                                \
       
  1240     struct                                                                   \
       
  1241     {                                                                        \
       
  1242       struct lut_node_3 *node;                                               \
       
  1243       mlib_s32 q;                                                            \
       
  1244     } stack[ BITS ];                                                         \
       
  1245     mlib_s32 stack_pointer = 0;                                              \
       
  1246                                                                              \
       
  1247     c[ 0 ] = *channels[ 0 ] - SUBTRACTION;                                   \
       
  1248     c[ 1 ] = *channels[ 1 ] - SUBTRACTION;                                   \
       
  1249     c[ 2 ] = *channels[ 2 ] - SUBTRACTION;                                   \
       
  1250                                                                              \
       
  1251     do                                                                       \
       
  1252     {                                                                        \
       
  1253       mlib_s32 q;                                                            \
       
  1254       mlib_u32 current_size = 1 << pass;                                     \
       
  1255                                                                              \
       
  1256       q = ( ( c[ 0 ] >> pass ) & 1 ) |                                       \
       
  1257         ( ( ( c[ 1 ] << 1 ) >> pass ) & 2 ) |                                \
       
  1258         ( ( ( c[ 2 ] << 2 ) >> pass ) & 4 );                                 \
       
  1259                                                                              \
       
  1260       position[ 0 ] |= c[ 0 ] & current_size;                                \
       
  1261       position[ 1 ] |= c[ 1 ] & current_size;                                \
       
  1262       position[ 2 ] |= c[ 2 ] & current_size;                                \
       
  1263                                                                              \
       
  1264       if( node->tag & ( 1 << q ) )                                           \
       
  1265       {                                                                      \
       
  1266         /*                                                                   \
       
  1267           Here is a cell with one color. We need to be sure it's             \
       
  1268           the one that is the closest to our color                           \
       
  1269         */                                                                   \
       
  1270         mlib_s32 palindex = node->contents.index[ q ];                       \
       
  1271         mlib_u32 palc[ 3 ];                                                  \
       
  1272         mlib_s32 identical;                                                  \
       
  1273                                                                              \
       
  1274         palc[ 0 ] = p[ 0 ][ palindex ] - SUBTRACTION;                        \
       
  1275         palc[ 1 ] = p[ 1 ][ palindex ] - SUBTRACTION;                        \
       
  1276         palc[ 2 ] = p[ 2 ][ palindex ] - SUBTRACTION;                        \
       
  1277                                                                              \
       
  1278         identical = ( palc[ 0 ] - c[ 0 ] ) | ( palc[ 1 ] - c[ 1 ] ) |        \
       
  1279           ( palc[ 2 ] - c[ 2 ] );                                            \
       
  1280                                                                              \
       
  1281         if( !identical || BITS - pass == bits )                              \
       
  1282         {                                                                    \
       
  1283           /* Oh, here it is :) */                                            \
       
  1284           dst[ j ] = palindex + s->offset;                                   \
       
  1285           we_found_it = 1;                                                   \
       
  1286         }                                                                    \
       
  1287         else                                                                 \
       
  1288         {                                                                    \
       
  1289           mlib_u32 distance;                                                 \
       
  1290           /* First index is the channel, second is the number of the         \
       
  1291              side */                                                         \
       
  1292           mlib_s32 found_color;                                              \
       
  1293           mlib_s32 continue_up;                                              \
       
  1294                                                                              \
       
  1295           distance = FIND_DISTANCE_3( c[ 0 ], palc[ 0 ],                     \
       
  1296             c[ 1 ], palc[ 1 ], c[ 2 ], palc[ 2 ], SHIFT );                   \
       
  1297           found_color = palindex;                                            \
       
  1298                                                                              \
       
  1299           do                                                                 \
       
  1300           {                                                                  \
       
  1301             mlib_s32 check_corner;                                           \
       
  1302                                                                              \
       
  1303             /*                                                               \
       
  1304               Neibours are enumerated in a cicle:                            \
       
  1305               0 - between quadrants 0 and 1,                                 \
       
  1306               1 - between quadrants 1 and 2 and                              \
       
  1307               2 - between quadrants 2 and 0                                  \
       
  1308             */                                                               \
       
  1309             mlib_s32 check_neibours[ 3 ];                                    \
       
  1310                                                                              \
       
  1311             /*                                                               \
       
  1312               Others are three two neibour quadrants                         \
       
  1313                                                                              \
       
  1314               Side number is [ <number of the coordinate >][ <the bit        \
       
  1315               in the quadrant number of the corner, corresponding to         \
       
  1316               this coordinate> ], e.g. 2 is 0..010b, so the sides it has     \
       
  1317               near are:                                                      \
       
  1318               [ 0 (coordinate number) ][ 0 (bit 0 in the number) ]           \
       
  1319               [ 1 (coordinate number) ][ 1 (bit 1 in the number) ]           \
       
  1320                                                                              \
       
  1321               Now we can look in the three nearest quadrants. Do             \
       
  1322               we really need it ? Check it.                                  \
       
  1323             */                                                               \
       
  1324                                                                              \
       
  1325             check_corner = check_neibours[ 0 ] = check_neibours[ 1 ] =       \
       
  1326               check_neibours[ 2 ] = 0;                                       \
       
  1327             continue_up = 0;                                                 \
       
  1328                                                                              \
       
  1329             if( q & 1 )                                                      \
       
  1330             {                                                                \
       
  1331               BINARY_TREE_EXPLORE_LEFT_3( 0, SOURCE_IMAGE, 2, 0,             \
       
  1332                 SUBTRACTION, SHIFT );                                        \
       
  1333             }                                                                \
       
  1334             else                                                             \
       
  1335             {                                                                \
       
  1336               BINARY_TREE_EXPLORE_RIGHT_3( 0, COLOR_MAX, SOURCE_IMAGE, 2, 0, \
       
  1337                 SUBTRACTION, SHIFT );                                        \
       
  1338             }                                                                \
       
  1339                                                                              \
       
  1340             if( q & 2 )                                                      \
       
  1341             {                                                                \
       
  1342               BINARY_TREE_EXPLORE_LEFT_3( 1, SOURCE_IMAGE, 0, 1,             \
       
  1343                 SUBTRACTION, SHIFT );                                        \
       
  1344             }                                                                \
       
  1345             else                                                             \
       
  1346             {                                                                \
       
  1347               BINARY_TREE_EXPLORE_RIGHT_3( 1, COLOR_MAX, SOURCE_IMAGE, 0, 1, \
       
  1348                 SUBTRACTION, SHIFT );                                        \
       
  1349             }                                                                \
       
  1350                                                                              \
       
  1351             if( q & 4 )                                                      \
       
  1352             {                                                                \
       
  1353               BINARY_TREE_EXPLORE_LEFT_3( 2, SOURCE_IMAGE, 1, 2,             \
       
  1354                 SUBTRACTION, SHIFT );                                        \
       
  1355             }                                                                \
       
  1356             else                                                             \
       
  1357             {                                                                \
       
  1358               BINARY_TREE_EXPLORE_RIGHT_3( 2, COLOR_MAX, SOURCE_IMAGE, 1, 2, \
       
  1359                 SUBTRACTION, SHIFT );                                        \
       
  1360             }                                                                \
       
  1361                                                                              \
       
  1362             if( check_neibours[ 0 ] >= 2 )                                   \
       
  1363             {                                                                \
       
  1364               mlib_s32 qq = q ^ 3;                                           \
       
  1365               CHECK_QUADRANT_##SOURCE_IMAGE##_3( qq );                       \
       
  1366             }                                                                \
       
  1367                                                                              \
       
  1368             if( check_neibours[ 1 ] >= 2 )                                   \
       
  1369             {                                                                \
       
  1370               mlib_s32 qq = q ^ 6;                                           \
       
  1371               CHECK_QUADRANT_##SOURCE_IMAGE##_3( qq );                       \
       
  1372             }                                                                \
       
  1373                                                                              \
       
  1374             if( check_neibours[ 2 ] >= 2 )                                   \
       
  1375             {                                                                \
       
  1376               mlib_s32 qq = q ^ 5;                                           \
       
  1377               CHECK_QUADRANT_##SOURCE_IMAGE##_3( qq );                       \
       
  1378             }                                                                \
       
  1379                                                                              \
       
  1380             if( check_corner >= 3 )                                          \
       
  1381             {                                                                \
       
  1382               mlib_s32 qq = q ^ 7;                                           \
       
  1383               CHECK_QUADRANT_##SOURCE_IMAGE##_3( qq );                       \
       
  1384             }                                                                \
       
  1385                                                                              \
       
  1386             if( q & 1 )                                                      \
       
  1387             {                                                                \
       
  1388               BINARY_TREE_SEARCH_RIGHT( 0, COLOR_MAX, SHIFT );               \
       
  1389             }                                                                \
       
  1390             else                                                             \
       
  1391             {                                                                \
       
  1392               BINARY_TREE_SEARCH_LEFT( 0, SHIFT );                           \
       
  1393             }                                                                \
       
  1394                                                                              \
       
  1395             if( q & 2 )                                                      \
       
  1396             {                                                                \
       
  1397               BINARY_TREE_SEARCH_RIGHT( 1, COLOR_MAX, SHIFT );               \
       
  1398             }                                                                \
       
  1399             else                                                             \
       
  1400             {                                                                \
       
  1401               BINARY_TREE_SEARCH_LEFT( 1, SHIFT );                           \
       
  1402             }                                                                \
       
  1403                                                                              \
       
  1404             if( q & 4 )                                                      \
       
  1405             {                                                                \
       
  1406               BINARY_TREE_SEARCH_RIGHT( 2, COLOR_MAX, SHIFT );               \
       
  1407             }                                                                \
       
  1408             else                                                             \
       
  1409             {                                                                \
       
  1410               BINARY_TREE_SEARCH_LEFT( 2, SHIFT );                           \
       
  1411             }                                                                \
       
  1412                                                                              \
       
  1413             position[ 0 ] &= ~( c[ 0 ] & current_size );                     \
       
  1414             position[ 1 ] &= ~( c[ 1 ] & current_size );                     \
       
  1415             position[ 2 ] &= ~( c[ 2 ] & current_size );                     \
       
  1416                                                                              \
       
  1417             current_size <<= 1;                                              \
       
  1418                                                                              \
       
  1419             pass++;                                                          \
       
  1420                                                                              \
       
  1421             stack_pointer--;                                                 \
       
  1422             q = stack[ stack_pointer ].q;                                    \
       
  1423             node = stack[ stack_pointer ].node;                              \
       
  1424           } while( continue_up );                                            \
       
  1425                                                                              \
       
  1426           dst[ j ] = found_color + s->offset;                                \
       
  1427                                                                              \
       
  1428           we_found_it = 1;                                                   \
       
  1429         }                                                                    \
       
  1430       }                                                                      \
       
  1431       else if( node->contents.quadrants[ q ] )                               \
       
  1432       {                                                                      \
       
  1433         /* Descend one level */                                              \
       
  1434         stack[ stack_pointer ].node = node;                                  \
       
  1435         stack[ stack_pointer++ ].q = q;                                      \
       
  1436         node = node->contents.quadrants[ q ];                                \
       
  1437       }                                                                      \
       
  1438       else                                                                   \
       
  1439       {                                                                      \
       
  1440         /* Found the empty quadrant. Look around */                          \
       
  1441         mlib_u32 distance = MLIB_U32_MAX;                                    \
       
  1442         mlib_s32 found_color;                                                \
       
  1443         mlib_s32 continue_up;                                                \
       
  1444                                                                              \
       
  1445         /*                                                                   \
       
  1446           As we had come to this level, it is warranted that there           \
       
  1447           are other points on this level near the empty quadrant             \
       
  1448         */                                                                   \
       
  1449         do                                                                   \
       
  1450         {                                                                    \
       
  1451           mlib_s32 check_corner;                                             \
       
  1452           mlib_s32 check_neibours[ 3 ];                                      \
       
  1453                                                                              \
       
  1454           check_corner = check_neibours[ 0 ] = check_neibours[ 1 ] =         \
       
  1455             check_neibours[ 2 ] = 0;                                         \
       
  1456           continue_up = 0;                                                   \
       
  1457                                                                              \
       
  1458           if( q & 1 )                                                        \
       
  1459           {                                                                  \
       
  1460             BINARY_TREE_EXPLORE_LEFT_3( 0, SOURCE_IMAGE, 2, 0,               \
       
  1461               SUBTRACTION, SHIFT );                                          \
       
  1462           }                                                                  \
       
  1463           else                                                               \
       
  1464           {                                                                  \
       
  1465             BINARY_TREE_EXPLORE_RIGHT_3( 0, COLOR_MAX, SOURCE_IMAGE, 2, 0,   \
       
  1466               SUBTRACTION, SHIFT );                                          \
       
  1467           }                                                                  \
       
  1468                                                                              \
       
  1469           if( q & 2 )                                                        \
       
  1470           {                                                                  \
       
  1471             BINARY_TREE_EXPLORE_LEFT_3( 1, SOURCE_IMAGE, 0, 1,               \
       
  1472               SUBTRACTION, SHIFT );                                          \
       
  1473           }                                                                  \
       
  1474           else                                                               \
       
  1475           {                                                                  \
       
  1476             BINARY_TREE_EXPLORE_RIGHT_3( 1, COLOR_MAX, SOURCE_IMAGE, 0, 1,   \
       
  1477               SUBTRACTION, SHIFT );                                          \
       
  1478           }                                                                  \
       
  1479                                                                              \
       
  1480           if( q & 4 )                                                        \
       
  1481           {                                                                  \
       
  1482             BINARY_TREE_EXPLORE_LEFT_3( 2, SOURCE_IMAGE, 1, 2,               \
       
  1483               SUBTRACTION, SHIFT );                                          \
       
  1484           }                                                                  \
       
  1485           else                                                               \
       
  1486           {                                                                  \
       
  1487             BINARY_TREE_EXPLORE_RIGHT_3( 2, COLOR_MAX, SOURCE_IMAGE, 1, 2,   \
       
  1488               SUBTRACTION, SHIFT );                                          \
       
  1489           }                                                                  \
       
  1490                                                                              \
       
  1491           if( check_neibours[ 0 ] >= 2 )                                     \
       
  1492           {                                                                  \
       
  1493             mlib_s32 qq = q ^ 3;                                             \
       
  1494             CHECK_QUADRANT_##SOURCE_IMAGE##_3( qq );                         \
       
  1495           }                                                                  \
       
  1496                                                                              \
       
  1497           if( check_neibours[ 1 ] >= 2 )                                     \
       
  1498           {                                                                  \
       
  1499             mlib_s32 qq = q ^ 6;                                             \
       
  1500             CHECK_QUADRANT_##SOURCE_IMAGE##_3( qq );                         \
       
  1501           }                                                                  \
       
  1502                                                                              \
       
  1503           if( check_neibours[ 2 ] >= 2 )                                     \
       
  1504           {                                                                  \
       
  1505             mlib_s32 qq = q ^ 5;                                             \
       
  1506             CHECK_QUADRANT_##SOURCE_IMAGE##_3( qq );                         \
       
  1507           }                                                                  \
       
  1508                                                                              \
       
  1509           if( check_corner >= 3 )                                            \
       
  1510           {                                                                  \
       
  1511             mlib_s32 qq = q ^ 7;                                             \
       
  1512             CHECK_QUADRANT_##SOURCE_IMAGE##_3( qq );                         \
       
  1513           }                                                                  \
       
  1514                                                                              \
       
  1515           if( q & 1 )                                                        \
       
  1516           {                                                                  \
       
  1517             BINARY_TREE_SEARCH_RIGHT( 0, COLOR_MAX, SHIFT );                 \
       
  1518           }                                                                  \
       
  1519           else                                                               \
       
  1520           {                                                                  \
       
  1521             BINARY_TREE_SEARCH_LEFT( 0, SHIFT );                             \
       
  1522           }                                                                  \
       
  1523                                                                              \
       
  1524           if( q & 2 )                                                        \
       
  1525           {                                                                  \
       
  1526             BINARY_TREE_SEARCH_RIGHT( 1, COLOR_MAX, SHIFT );                 \
       
  1527           }                                                                  \
       
  1528           else                                                               \
       
  1529           {                                                                  \
       
  1530             BINARY_TREE_SEARCH_LEFT( 1, SHIFT );                             \
       
  1531           }                                                                  \
       
  1532                                                                              \
       
  1533           if( q & 4 )                                                        \
       
  1534           {                                                                  \
       
  1535             BINARY_TREE_SEARCH_RIGHT( 2, COLOR_MAX, SHIFT );                 \
       
  1536           }                                                                  \
       
  1537           else                                                               \
       
  1538           {                                                                  \
       
  1539             BINARY_TREE_SEARCH_LEFT( 2, SHIFT );                             \
       
  1540           }                                                                  \
       
  1541                                                                              \
       
  1542           position[ 0 ] &= ~( c[ 0 ] & current_size );                       \
       
  1543           position[ 1 ] &= ~( c[ 1 ] & current_size );                       \
       
  1544           position[ 2 ] &= ~( c[ 2 ] & current_size );                       \
       
  1545                                                                              \
       
  1546           current_size <<= 1;                                                \
       
  1547                                                                              \
       
  1548           pass++;                                                            \
       
  1549                                                                              \
       
  1550           stack_pointer--;                                                   \
       
  1551           q = stack[ stack_pointer ].q;                                      \
       
  1552           node = stack[ stack_pointer ].node;                                \
       
  1553         } while( continue_up );                                              \
       
  1554                                                                              \
       
  1555         dst[ j ] = found_color + s->offset;                                  \
       
  1556         we_found_it = 1;                                                     \
       
  1557       }                                                                      \
       
  1558                                                                              \
       
  1559       pass--;                                                                \
       
  1560                                                                              \
       
  1561     } while( !we_found_it );                                                 \
       
  1562                                                                              \
       
  1563     channels[ 0 ] += STEP;                                                   \
       
  1564     channels[ 1 ] += STEP;                                                   \
       
  1565     channels[ 2 ] += STEP;                                                   \
       
  1566   }                                                                          \
       
  1567 }
       
  1568 
       
  1569 /***************************************************************/
       
  1570 #define CHECK_QUADRANT_U8_4( qq )                               \
       
  1571 {                                                               \
       
  1572   if( node->tag & ( 1 << qq ) )                                 \
       
  1573   {                                                             \
       
  1574     /* Here is another color cell. Check the distance */        \
       
  1575     mlib_s32 new_found_color = node->contents.index[ qq ];      \
       
  1576     mlib_u32 newdistance = FIND_DISTANCE_4( c[ 0 ],             \
       
  1577       p[ 0 ][ new_found_color ], c[ 1 ],                        \
       
  1578       p[ 1 ][ new_found_color ], c[ 2 ],                        \
       
  1579       p[ 2 ][ new_found_color ], c[ 3 ],                        \
       
  1580       p[ 3 ][ new_found_color ], 0 );                           \
       
  1581                                                                 \
       
  1582     if( newdistance < distance )                                \
       
  1583     {                                                           \
       
  1584       found_color = new_found_color;                            \
       
  1585       distance = newdistance;                                   \
       
  1586     }                                                           \
       
  1587   }                                                             \
       
  1588   else if( node->contents.quadrants[ qq ] )                     \
       
  1589     /* Here is a full node. Just explore it all */              \
       
  1590     distance = mlib_search_quadrant_U8_4(                       \
       
  1591       node->contents.quadrants[ qq ], distance, &found_color,   \
       
  1592       c[ 0 ], c[ 1 ], c[ 2 ], c[ 3 ], p );                      \
       
  1593 /* Else there is just an empty cell */                          \
       
  1594 }
       
  1595 
       
  1596 /***************************************************************/
       
  1597 #define CHECK_QUADRANT_S16_4( qq )                              \
       
  1598 {                                                               \
       
  1599   if( node->tag & ( 1 << qq ) )                                 \
       
  1600   {                                                             \
       
  1601     /* Here is another color cell. Check the distance */        \
       
  1602     mlib_s32 new_found_color = node->contents.index[ qq ];      \
       
  1603     mlib_u32 palc0, palc1, palc2, palc3, newdistance;           \
       
  1604                                                                 \
       
  1605     palc0 = p[ 0 ][ new_found_color ] - MLIB_S16_MIN;           \
       
  1606     palc1 = p[ 1 ][ new_found_color ] - MLIB_S16_MIN;           \
       
  1607     palc2 = p[ 2 ][ new_found_color ] - MLIB_S16_MIN;           \
       
  1608     palc3 = p[ 3 ][ new_found_color ] - MLIB_S16_MIN;           \
       
  1609                                                                 \
       
  1610     newdistance = FIND_DISTANCE_4( c[ 0 ], palc0,               \
       
  1611       c[ 1 ], palc1,                                            \
       
  1612       c[ 2 ], palc2,                                            \
       
  1613       c[ 3 ], palc3, 2 );                                       \
       
  1614                                                                 \
       
  1615     if( newdistance < distance )                                \
       
  1616     {                                                           \
       
  1617       found_color = new_found_color;                            \
       
  1618       distance = newdistance;                                   \
       
  1619     }                                                           \
       
  1620   }                                                             \
       
  1621   else if( node->contents.quadrants[ qq ] )                     \
       
  1622     /* Here is a full node. Just explore it all */              \
       
  1623     distance = mlib_search_quadrant_S16_4(                      \
       
  1624       node->contents.quadrants[ qq ], distance, &found_color,   \
       
  1625       c[ 0 ], c[ 1 ], c[ 2 ], c[ 3 ], p );                      \
       
  1626 /* Else there is just an empty cell */                          \
       
  1627 }
       
  1628 
       
  1629 /***************************************************************/
       
  1630 #define BINARY_TREE_SEARCH_4( SOURCE_IMAGE, POINTER_TYPE, BITS,               \
       
  1631   COLOR_MAX, SUBTRACTION, SHIFT )                                             \
       
  1632 {                                                                             \
       
  1633   const POINTER_TYPE *channels[ 4 ], *p[ 4 ];                                 \
       
  1634   mlib_u32 c[ 4 ];                                                            \
       
  1635   mlib_s32 j;                                                                 \
       
  1636                                                                               \
       
  1637   p[ 0 ] = s->lut[ 0 ];                                                       \
       
  1638   p[ 1 ] = s->lut[ 1 ];                                                       \
       
  1639   p[ 2 ] = s->lut[ 2 ];                                                       \
       
  1640   p[ 3 ] = s->lut[ 3 ];                                                       \
       
  1641   channels[ 0 ] = src;                                                        \
       
  1642   channels[ 1 ] = src + 1;                                                    \
       
  1643   channels[ 2 ] = src + 2;                                                    \
       
  1644   channels[ 3 ] = src + 3;                                                    \
       
  1645                                                                               \
       
  1646   for( j = 0; j < length; j++ )                                               \
       
  1647   {                                                                           \
       
  1648     mlib_s32 pass = BITS - 1;                                                 \
       
  1649     mlib_u32 position[ 4 ] = { 0, 0, 0, 0 };                                  \
       
  1650     mlib_s32 we_found_it = 0;                                                 \
       
  1651     struct lut_node_4 *node = s->table;                                       \
       
  1652     /* Stack pointer pointers to the first free element of stack. */          \
       
  1653     /* The node we are in is in the `node' */                                 \
       
  1654     struct                                                                    \
       
  1655     {                                                                         \
       
  1656       struct lut_node_4 *node;                                                \
       
  1657       mlib_s32 q;                                                             \
       
  1658     } stack[ BITS ];                                                          \
       
  1659     mlib_s32 stack_pointer = 0;                                               \
       
  1660                                                                               \
       
  1661     c[ 0 ] = *channels[ 0 ] - SUBTRACTION;                                    \
       
  1662     c[ 1 ] = *channels[ 1 ] - SUBTRACTION;                                    \
       
  1663     c[ 2 ] = *channels[ 2 ] - SUBTRACTION;                                    \
       
  1664     c[ 3 ] = *channels[ 3 ] - SUBTRACTION;                                    \
       
  1665                                                                               \
       
  1666     do                                                                        \
       
  1667     {                                                                         \
       
  1668       mlib_s32 q;                                                             \
       
  1669       mlib_u32 current_size = 1 << pass;                                      \
       
  1670                                                                               \
       
  1671       q = ( ( c[ 0 ] >> pass ) & 1 ) |                                        \
       
  1672         ( ( ( c[ 1 ] << 1 ) >> pass ) & 2 ) |                                 \
       
  1673         ( ( ( c[ 2 ] << 2 ) >> pass ) & 4 ) |                                 \
       
  1674         ( ( ( c[ 3 ] << 3 ) >> pass ) & 8 );                                  \
       
  1675                                                                               \
       
  1676       position[ 0 ] |= c[ 0 ] & current_size;                                 \
       
  1677       position[ 1 ] |= c[ 1 ] & current_size;                                 \
       
  1678       position[ 2 ] |= c[ 2 ] & current_size;                                 \
       
  1679       position[ 3 ] |= c[ 3 ] & current_size;                                 \
       
  1680                                                                               \
       
  1681       if( node->tag & ( 1 << q ) )                                            \
       
  1682       {                                                                       \
       
  1683         /*                                                                    \
       
  1684           Here is a cell with one color. We need to be sure it's              \
       
  1685           the one that is the closest to our color                            \
       
  1686         */                                                                    \
       
  1687         mlib_s32 palindex = node->contents.index[ q ];                        \
       
  1688         mlib_u32 palc[ 4 ];                                                   \
       
  1689         mlib_s32 identical;                                                   \
       
  1690                                                                               \
       
  1691         palc[ 0 ] = p[ 0 ][ palindex ] - SUBTRACTION;                         \
       
  1692         palc[ 1 ] = p[ 1 ][ palindex ] - SUBTRACTION;                         \
       
  1693         palc[ 2 ] = p[ 2 ][ palindex ] - SUBTRACTION;                         \
       
  1694         palc[ 3 ] = p[ 3 ][ palindex ] - SUBTRACTION;                         \
       
  1695                                                                               \
       
  1696         identical = ( palc[ 0 ] - c[ 0 ] ) | ( palc[ 1 ] - c[ 1 ] ) |         \
       
  1697           ( palc[ 2 ] - c[ 2 ] ) | ( palc[ 3 ] - c[ 3 ] );                    \
       
  1698                                                                               \
       
  1699         if( !identical || BITS - pass == bits )                               \
       
  1700         {                                                                     \
       
  1701           /* Oh, here it is :) */                                             \
       
  1702           dst[ j ] = palindex + s->offset;                                    \
       
  1703           we_found_it = 1;                                                    \
       
  1704         }                                                                     \
       
  1705         else                                                                  \
       
  1706         {                                                                     \
       
  1707           mlib_u32 distance;                                                  \
       
  1708           /* First index is the channel, second is the number of the          \
       
  1709              side */                                                          \
       
  1710           mlib_s32 found_color;                                               \
       
  1711           mlib_s32 continue_up;                                               \
       
  1712                                                                               \
       
  1713           distance = FIND_DISTANCE_4( c[ 0 ], palc[ 0 ],                      \
       
  1714             c[ 1 ], palc[ 1 ], c[ 2 ], palc[ 2 ], c[ 3 ], palc[ 3 ], SHIFT ); \
       
  1715           found_color = palindex;                                             \
       
  1716                                                                               \
       
  1717           do                                                                  \
       
  1718           {                                                                   \
       
  1719             mlib_s32 check_corner;                                            \
       
  1720             mlib_s32 check_neibours[ 6 ];                                     \
       
  1721             mlib_s32 check_far_neibours[ 4 ];                                 \
       
  1722                                                                               \
       
  1723             /*                                                                \
       
  1724               Check neibours: quadrants that are different by 2 bits          \
       
  1725               from the quadrant, that we are in:                              \
       
  1726               3 -  0                                                          \
       
  1727               5 -  1                                                          \
       
  1728               6 -  2                                                          \
       
  1729               9 -  3                                                          \
       
  1730               10 - 4                                                          \
       
  1731               12 - 5                                                          \
       
  1732               Far quadrants: different by 3 bits:                             \
       
  1733               7  - 0                                                          \
       
  1734               11 - 1                                                          \
       
  1735               13 - 2                                                          \
       
  1736               14 - 3                                                          \
       
  1737             */                                                                \
       
  1738                                                                               \
       
  1739             check_neibours[ 0 ] = check_neibours[ 1 ] =                       \
       
  1740               check_neibours[ 2 ] = check_neibours[ 3 ] =                     \
       
  1741               check_neibours[ 4 ] = check_neibours[ 5 ] = 0;                  \
       
  1742             continue_up = 0;                                                  \
       
  1743                                                                               \
       
  1744             if( q & 1 )                                                       \
       
  1745             {                                                                 \
       
  1746               BINARY_TREE_EXPLORE_LEFT_4( 0, SOURCE_IMAGE, 0, 1, 3,           \
       
  1747                 SUBTRACTION, SHIFT );                                         \
       
  1748             }                                                                 \
       
  1749             else                                                              \
       
  1750             {                                                                 \
       
  1751               BINARY_TREE_EXPLORE_RIGHT_4( 0, COLOR_MAX, SOURCE_IMAGE,        \
       
  1752                 0, 1, 3, SUBTRACTION, SHIFT );                                \
       
  1753             }                                                                 \
       
  1754                                                                               \
       
  1755             if( q & 2 )                                                       \
       
  1756             {                                                                 \
       
  1757               BINARY_TREE_EXPLORE_LEFT_4( 1, SOURCE_IMAGE, 0, 2, 4,           \
       
  1758                 SUBTRACTION, SHIFT );                                         \
       
  1759             }                                                                 \
       
  1760             else                                                              \
       
  1761             {                                                                 \
       
  1762               BINARY_TREE_EXPLORE_RIGHT_4( 1, COLOR_MAX, SOURCE_IMAGE,        \
       
  1763                 0, 2, 4, SUBTRACTION, SHIFT );                                \
       
  1764             }                                                                 \
       
  1765                                                                               \
       
  1766             if( q & 4 )                                                       \
       
  1767             {                                                                 \
       
  1768               BINARY_TREE_EXPLORE_LEFT_4( 2, SOURCE_IMAGE, 1, 2, 5,           \
       
  1769                 SUBTRACTION, SHIFT );                                         \
       
  1770             }                                                                 \
       
  1771             else                                                              \
       
  1772             {                                                                 \
       
  1773               BINARY_TREE_EXPLORE_RIGHT_4( 2, COLOR_MAX, SOURCE_IMAGE,        \
       
  1774                 1, 2, 5, SUBTRACTION, SHIFT );                                \
       
  1775             }                                                                 \
       
  1776                                                                               \
       
  1777             if( q & 8 )                                                       \
       
  1778             {                                                                 \
       
  1779               BINARY_TREE_EXPLORE_LEFT_4( 3, SOURCE_IMAGE, 3, 4, 5,           \
       
  1780                 SUBTRACTION, SHIFT );                                         \
       
  1781             }                                                                 \
       
  1782             else                                                              \
       
  1783             {                                                                 \
       
  1784               BINARY_TREE_EXPLORE_RIGHT_4( 3, COLOR_MAX, SOURCE_IMAGE,        \
       
  1785                 3, 4, 5, SUBTRACTION, SHIFT );                                \
       
  1786             }                                                                 \
       
  1787                                                                               \
       
  1788             check_far_neibours[ 0 ] = check_neibours[ 0 ] +                   \
       
  1789               check_neibours[ 1 ] + check_neibours[ 2 ];                      \
       
  1790             check_far_neibours[ 1 ] = check_neibours[ 0 ] +                   \
       
  1791               check_neibours[ 3 ] + check_neibours[ 4 ];                      \
       
  1792             check_far_neibours[ 2 ] = check_neibours[ 1 ] +                   \
       
  1793               check_neibours[ 3 ] + check_neibours[ 5 ];                      \
       
  1794             check_far_neibours[ 3 ] = check_neibours[ 2 ] +                   \
       
  1795               check_neibours[ 4 ] + check_neibours[ 5 ];                      \
       
  1796                                                                               \
       
  1797             check_corner = check_far_neibours[ 0 ] +                          \
       
  1798               check_far_neibours[ 1 ] +                                       \
       
  1799               check_far_neibours[ 2 ] +                                       \
       
  1800               check_far_neibours[ 3 ];                                        \
       
  1801                                                                               \
       
  1802             if( check_neibours[ 0 ] >= 2 )                                    \
       
  1803             {                                                                 \
       
  1804               mlib_s32 qq = q ^ 3;                                            \
       
  1805               CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                        \
       
  1806             }                                                                 \
       
  1807                                                                               \
       
  1808             if( check_neibours[ 1 ] >= 2 )                                    \
       
  1809             {                                                                 \
       
  1810               mlib_s32 qq = q ^ 5;                                            \
       
  1811               CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                        \
       
  1812             }                                                                 \
       
  1813                                                                               \
       
  1814             if( check_neibours[ 2 ] >= 2 )                                    \
       
  1815             {                                                                 \
       
  1816               mlib_s32 qq = q ^ 6;                                            \
       
  1817               CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                        \
       
  1818             }                                                                 \
       
  1819                                                                               \
       
  1820             if( check_neibours[ 3 ] >= 2 )                                    \
       
  1821             {                                                                 \
       
  1822               mlib_s32 qq = q ^ 9;                                            \
       
  1823               CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                        \
       
  1824             }                                                                 \
       
  1825                                                                               \
       
  1826             if( check_neibours[ 4 ] >= 2 )                                    \
       
  1827             {                                                                 \
       
  1828               mlib_s32 qq = q ^ 10;                                           \
       
  1829               CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                        \
       
  1830             }                                                                 \
       
  1831                                                                               \
       
  1832             if( check_neibours[ 5 ] >= 2 )                                    \
       
  1833             {                                                                 \
       
  1834               mlib_s32 qq = q ^ 12;                                           \
       
  1835               CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                        \
       
  1836             }                                                                 \
       
  1837                                                                               \
       
  1838             if( check_far_neibours[ 0 ] >= 3 )                                \
       
  1839             {                                                                 \
       
  1840               mlib_s32 qq = q ^ 7;                                            \
       
  1841               CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                        \
       
  1842             }                                                                 \
       
  1843                                                                               \
       
  1844             if( check_far_neibours[ 1 ] >= 3 )                                \
       
  1845             {                                                                 \
       
  1846               mlib_s32 qq = q ^ 11;                                           \
       
  1847               CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                        \
       
  1848             }                                                                 \
       
  1849                                                                               \
       
  1850             if( check_far_neibours[ 2 ] >= 3 )                                \
       
  1851             {                                                                 \
       
  1852               mlib_s32 qq = q ^ 13;                                           \
       
  1853               CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                        \
       
  1854             }                                                                 \
       
  1855                                                                               \
       
  1856             if( check_far_neibours[ 3 ] >= 3 )                                \
       
  1857             {                                                                 \
       
  1858               mlib_s32 qq = q ^ 14;                                           \
       
  1859               CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                        \
       
  1860             }                                                                 \
       
  1861                                                                               \
       
  1862             if( check_corner >= 4 )                                           \
       
  1863             {                                                                 \
       
  1864               mlib_s32 qq = q ^ 15;                                           \
       
  1865               CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                        \
       
  1866             }                                                                 \
       
  1867                                                                               \
       
  1868             if( q & 1 )                                                       \
       
  1869             {                                                                 \
       
  1870               BINARY_TREE_SEARCH_RIGHT( 0, COLOR_MAX, SHIFT );                \
       
  1871             }                                                                 \
       
  1872             else                                                              \
       
  1873             {                                                                 \
       
  1874               BINARY_TREE_SEARCH_LEFT( 0, SHIFT );                            \
       
  1875             }                                                                 \
       
  1876                                                                               \
       
  1877             if( q & 2 )                                                       \
       
  1878             {                                                                 \
       
  1879               BINARY_TREE_SEARCH_RIGHT( 1, COLOR_MAX, SHIFT );                \
       
  1880             }                                                                 \
       
  1881             else                                                              \
       
  1882             {                                                                 \
       
  1883               BINARY_TREE_SEARCH_LEFT( 1, SHIFT );                            \
       
  1884             }                                                                 \
       
  1885                                                                               \
       
  1886             if( q & 4 )                                                       \
       
  1887             {                                                                 \
       
  1888               BINARY_TREE_SEARCH_RIGHT( 2, COLOR_MAX, SHIFT );                \
       
  1889             }                                                                 \
       
  1890             else                                                              \
       
  1891             {                                                                 \
       
  1892               BINARY_TREE_SEARCH_LEFT( 2, SHIFT );                            \
       
  1893             }                                                                 \
       
  1894                                                                               \
       
  1895             if( q & 8 )                                                       \
       
  1896             {                                                                 \
       
  1897               BINARY_TREE_SEARCH_RIGHT( 3, COLOR_MAX, SHIFT );                \
       
  1898             }                                                                 \
       
  1899             else                                                              \
       
  1900             {                                                                 \
       
  1901               BINARY_TREE_SEARCH_LEFT( 3, SHIFT );                            \
       
  1902             }                                                                 \
       
  1903                                                                               \
       
  1904             position[ 0 ] &= ~( c[ 0 ] & current_size );                      \
       
  1905             position[ 1 ] &= ~( c[ 1 ] & current_size );                      \
       
  1906             position[ 2 ] &= ~( c[ 2 ] & current_size );                      \
       
  1907             position[ 3 ] &= ~( c[ 3 ] & current_size );                      \
       
  1908                                                                               \
       
  1909             current_size <<= 1;                                               \
       
  1910                                                                               \
       
  1911             pass++;                                                           \
       
  1912                                                                               \
       
  1913             stack_pointer--;                                                  \
       
  1914             q = stack[ stack_pointer ].q;                                     \
       
  1915             node = stack[ stack_pointer ].node;                               \
       
  1916           } while( continue_up );                                             \
       
  1917                                                                               \
       
  1918           dst[ j ] = found_color + s->offset;                                 \
       
  1919           we_found_it = 1;                                                    \
       
  1920         }                                                                     \
       
  1921       }                                                                       \
       
  1922       else if( node->contents.quadrants[ q ] )                                \
       
  1923       {                                                                       \
       
  1924         /* Descend one level */                                               \
       
  1925         stack[ stack_pointer ].node = node;                                   \
       
  1926         stack[ stack_pointer++ ].q = q;                                       \
       
  1927         node = node->contents.quadrants[ q ];                                 \
       
  1928       }                                                                       \
       
  1929       else                                                                    \
       
  1930       {                                                                       \
       
  1931         /* Found the empty quadrant. Look around */                           \
       
  1932         mlib_u32 distance = MLIB_U32_MAX;                                     \
       
  1933         mlib_s32 found_color;                                                 \
       
  1934         mlib_s32 continue_up;                                                 \
       
  1935                                                                               \
       
  1936         /*                                                                    \
       
  1937           As we had come to this level, it is warranted that there            \
       
  1938           are other points on this level near the empty quadrant              \
       
  1939         */                                                                    \
       
  1940         do                                                                    \
       
  1941         {                                                                     \
       
  1942           mlib_s32 check_corner;                                              \
       
  1943           mlib_s32 check_neibours[ 6 ];                                       \
       
  1944           mlib_s32 check_far_neibours[ 4 ];                                   \
       
  1945                                                                               \
       
  1946           /*                                                                  \
       
  1947             Check neibours: quadrants that are different by 2 bits            \
       
  1948             from the quadrant, that we are in:                                \
       
  1949             3 -  0                                                            \
       
  1950             5 -  1                                                            \
       
  1951             6 -  2                                                            \
       
  1952             9 -  3                                                            \
       
  1953             10 - 4                                                            \
       
  1954             12 - 5                                                            \
       
  1955             Far quadrants: different by 3 bits:                               \
       
  1956             7  - 0                                                            \
       
  1957             11 - 1                                                            \
       
  1958             13 - 2                                                            \
       
  1959             14 - 3                                                            \
       
  1960           */                                                                  \
       
  1961                                                                               \
       
  1962           check_neibours[ 0 ] = check_neibours[ 1 ] =                         \
       
  1963             check_neibours[ 2 ] = check_neibours[ 3 ] =                       \
       
  1964             check_neibours[ 4 ] = check_neibours[ 5 ] = 0;                    \
       
  1965           continue_up = 0;                                                    \
       
  1966                                                                               \
       
  1967           if( q & 1 )                                                         \
       
  1968           {                                                                   \
       
  1969             BINARY_TREE_EXPLORE_LEFT_4( 0, SOURCE_IMAGE, 0, 1, 3,             \
       
  1970               SUBTRACTION, SHIFT );                                           \
       
  1971           }                                                                   \
       
  1972           else                                                                \
       
  1973           {                                                                   \
       
  1974             BINARY_TREE_EXPLORE_RIGHT_4( 0, COLOR_MAX, SOURCE_IMAGE,          \
       
  1975               0, 1, 3, SUBTRACTION, SHIFT );                                  \
       
  1976           }                                                                   \
       
  1977                                                                               \
       
  1978           if( q & 2 )                                                         \
       
  1979           {                                                                   \
       
  1980             BINARY_TREE_EXPLORE_LEFT_4( 1, SOURCE_IMAGE, 0, 2, 4,             \
       
  1981               SUBTRACTION, SHIFT );                                           \
       
  1982           }                                                                   \
       
  1983           else                                                                \
       
  1984           {                                                                   \
       
  1985             BINARY_TREE_EXPLORE_RIGHT_4( 1, COLOR_MAX, SOURCE_IMAGE,          \
       
  1986               0, 2, 4, SUBTRACTION, SHIFT );                                  \
       
  1987           }                                                                   \
       
  1988                                                                               \
       
  1989           if( q & 4 )                                                         \
       
  1990           {                                                                   \
       
  1991             BINARY_TREE_EXPLORE_LEFT_4( 2, SOURCE_IMAGE, 1, 2, 5,             \
       
  1992               SUBTRACTION, SHIFT );                                           \
       
  1993           }                                                                   \
       
  1994           else                                                                \
       
  1995           {                                                                   \
       
  1996             BINARY_TREE_EXPLORE_RIGHT_4( 2, COLOR_MAX, SOURCE_IMAGE,          \
       
  1997               1, 2, 5, SUBTRACTION, SHIFT );                                  \
       
  1998           }                                                                   \
       
  1999                                                                               \
       
  2000           if( q & 8 )                                                         \
       
  2001           {                                                                   \
       
  2002             BINARY_TREE_EXPLORE_LEFT_4( 3, SOURCE_IMAGE, 3, 4, 5,             \
       
  2003               SUBTRACTION, SHIFT );                                           \
       
  2004           }                                                                   \
       
  2005           else                                                                \
       
  2006           {                                                                   \
       
  2007             BINARY_TREE_EXPLORE_RIGHT_4( 3, COLOR_MAX, SOURCE_IMAGE,          \
       
  2008               3, 4, 5, SUBTRACTION, SHIFT );                                  \
       
  2009           }                                                                   \
       
  2010                                                                               \
       
  2011           check_far_neibours[ 0 ] = check_neibours[ 0 ] +                     \
       
  2012             check_neibours[ 1 ] + check_neibours[ 2 ];                        \
       
  2013           check_far_neibours[ 1 ] = check_neibours[ 0 ] +                     \
       
  2014             check_neibours[ 3 ] + check_neibours[ 4 ];                        \
       
  2015           check_far_neibours[ 2 ] = check_neibours[ 1 ] +                     \
       
  2016             check_neibours[ 3 ] + check_neibours[ 5 ];                        \
       
  2017           check_far_neibours[ 3 ] = check_neibours[ 2 ] +                     \
       
  2018             check_neibours[ 4 ] + check_neibours[ 5 ];                        \
       
  2019                                                                               \
       
  2020           check_corner = check_far_neibours[ 0 ] +                            \
       
  2021             check_far_neibours[ 1 ] +                                         \
       
  2022             check_far_neibours[ 2 ] +                                         \
       
  2023             check_far_neibours[ 3 ];                                          \
       
  2024                                                                               \
       
  2025           if( check_neibours[ 0 ] >= 2 )                                      \
       
  2026           {                                                                   \
       
  2027             mlib_s32 qq = q ^ 3;                                              \
       
  2028             CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                          \
       
  2029           }                                                                   \
       
  2030                                                                               \
       
  2031           if( check_neibours[ 1 ] >= 2 )                                      \
       
  2032           {                                                                   \
       
  2033             mlib_s32 qq = q ^ 5;                                              \
       
  2034             CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                          \
       
  2035           }                                                                   \
       
  2036                                                                               \
       
  2037           if( check_neibours[ 2 ] >= 2 )                                      \
       
  2038           {                                                                   \
       
  2039             mlib_s32 qq = q ^ 6;                                              \
       
  2040             CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                          \
       
  2041           }                                                                   \
       
  2042                                                                               \
       
  2043           if( check_neibours[ 3 ] >= 2 )                                      \
       
  2044           {                                                                   \
       
  2045             mlib_s32 qq = q ^ 9;                                              \
       
  2046             CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                          \
       
  2047           }                                                                   \
       
  2048                                                                               \
       
  2049           if( check_neibours[ 4 ] >= 2 )                                      \
       
  2050           {                                                                   \
       
  2051             mlib_s32 qq = q ^ 10;                                             \
       
  2052             CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                          \
       
  2053           }                                                                   \
       
  2054                                                                               \
       
  2055           if( check_neibours[ 5 ] >= 2 )                                      \
       
  2056           {                                                                   \
       
  2057             mlib_s32 qq = q ^ 12;                                             \
       
  2058             CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                          \
       
  2059           }                                                                   \
       
  2060                                                                               \
       
  2061           if( check_far_neibours[ 0 ] >= 3 )                                  \
       
  2062           {                                                                   \
       
  2063             mlib_s32 qq = q ^ 7;                                              \
       
  2064             CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                          \
       
  2065           }                                                                   \
       
  2066                                                                               \
       
  2067           if( check_far_neibours[ 1 ] >= 3 )                                  \
       
  2068           {                                                                   \
       
  2069             mlib_s32 qq = q ^ 11;                                             \
       
  2070             CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                          \
       
  2071           }                                                                   \
       
  2072                                                                               \
       
  2073           if( check_far_neibours[ 2 ] >= 3 )                                  \
       
  2074           {                                                                   \
       
  2075             mlib_s32 qq = q ^ 13;                                             \
       
  2076             CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                          \
       
  2077           }                                                                   \
       
  2078                                                                               \
       
  2079           if( check_far_neibours[ 3 ] >= 3 )                                  \
       
  2080           {                                                                   \
       
  2081             mlib_s32 qq = q ^ 14;                                             \
       
  2082             CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                          \
       
  2083           }                                                                   \
       
  2084                                                                               \
       
  2085           if( check_corner >= 4 )                                             \
       
  2086           {                                                                   \
       
  2087             mlib_s32 qq = q ^ 15;                                             \
       
  2088             CHECK_QUADRANT_##SOURCE_IMAGE##_4( qq );                          \
       
  2089           }                                                                   \
       
  2090                                                                               \
       
  2091           if( q & 1 )                                                         \
       
  2092           {                                                                   \
       
  2093             BINARY_TREE_SEARCH_RIGHT( 0, COLOR_MAX, SHIFT );                  \
       
  2094           }                                                                   \
       
  2095           else                                                                \
       
  2096           {                                                                   \
       
  2097             BINARY_TREE_SEARCH_LEFT( 0, SHIFT );                              \
       
  2098           }                                                                   \
       
  2099                                                                               \
       
  2100           if( q & 2 )                                                         \
       
  2101           {                                                                   \
       
  2102             BINARY_TREE_SEARCH_RIGHT( 1, COLOR_MAX, SHIFT );                  \
       
  2103           }                                                                   \
       
  2104           else                                                                \
       
  2105           {                                                                   \
       
  2106             BINARY_TREE_SEARCH_LEFT( 1, SHIFT );                              \
       
  2107           }                                                                   \
       
  2108                                                                               \
       
  2109           if( q & 4 )                                                         \
       
  2110           {                                                                   \
       
  2111             BINARY_TREE_SEARCH_RIGHT( 2, COLOR_MAX, SHIFT );                  \
       
  2112           }                                                                   \
       
  2113           else                                                                \
       
  2114           {                                                                   \
       
  2115             BINARY_TREE_SEARCH_LEFT( 2, SHIFT );                              \
       
  2116           }                                                                   \
       
  2117                                                                               \
       
  2118           if( q & 8 )                                                         \
       
  2119           {                                                                   \
       
  2120             BINARY_TREE_SEARCH_RIGHT( 3, COLOR_MAX, SHIFT );                  \
       
  2121           }                                                                   \
       
  2122           else                                                                \
       
  2123           {                                                                   \
       
  2124             BINARY_TREE_SEARCH_LEFT( 3, SHIFT );                              \
       
  2125           }                                                                   \
       
  2126                                                                               \
       
  2127           position[ 0 ] &= ~( c[ 0 ] & current_size );                        \
       
  2128           position[ 1 ] &= ~( c[ 1 ] & current_size );                        \
       
  2129           position[ 2 ] &= ~( c[ 2 ] & current_size );                        \
       
  2130           position[ 3 ] &= ~( c[ 3 ] & current_size );                        \
       
  2131                                                                               \
       
  2132           current_size <<= 1;                                                 \
       
  2133                                                                               \
       
  2134           pass++;                                                             \
       
  2135                                                                               \
       
  2136           stack_pointer--;                                                    \
       
  2137           q = stack[ stack_pointer ].q;                                       \
       
  2138           node = stack[ stack_pointer ].node;                                 \
       
  2139         } while( continue_up );                                               \
       
  2140                                                                               \
       
  2141         dst[ j ] = found_color + s->offset;                                   \
       
  2142         we_found_it = 1;                                                      \
       
  2143       }                                                                       \
       
  2144                                                                               \
       
  2145       pass--;                                                                 \
       
  2146                                                                               \
       
  2147     } while( !we_found_it );                                                  \
       
  2148                                                                               \
       
  2149     channels[ 0 ] += 4;                                                       \
       
  2150     channels[ 1 ] += 4;                                                       \
       
  2151     channels[ 2 ] += 4;                                                       \
       
  2152     channels[ 3 ] += 4;                                                       \
       
  2153   }                                                                           \
       
  2154 }
       
  2155 
       
  2156 /***************************************************************/
       
  2157 #define FIND_NEAREST_U8_3_C( SHIFT, STEP )                      \
       
  2158   mlib_s32 i, k, k_min, min_dist, diff, mask;                   \
       
  2159   mlib_s32 offset = mlib_ImageGetLutOffset( s ) - 1;            \
       
  2160   mlib_s32 entries = s -> lutlength;                            \
       
  2161   mlib_d64 *double_lut = mlib_ImageGetLutDoubleData( s );       \
       
  2162   mlib_d64 col0, col1, col2;                                    \
       
  2163   mlib_d64 dist, len0, len1, len2;                              \
       
  2164                                                                 \
       
  2165   for ( i = 0; i < length; i++ ) {                              \
       
  2166     col0 = src[ STEP * i + SHIFT ];                             \
       
  2167     col1 = src[ STEP * i + 1 + SHIFT ];                         \
       
  2168     col2 = src[ STEP * i + 2 + SHIFT ];                         \
       
  2169     min_dist = MLIB_S32_MAX;                                    \
       
  2170     k_min = 1;                                                  \
       
  2171     len0 = double_lut[ 0 ] - col0;                              \
       
  2172     len1 = double_lut[ 1 ] - col1;                              \
       
  2173     len2 = double_lut[ 2 ] - col2;                              \
       
  2174                                                                 \
       
  2175     for ( k = 1; k <= entries; k++ ) {                          \
       
  2176       dist = len0 * len0;                                       \
       
  2177       len0 = double_lut[ 3 * k ] - col0;                        \
       
  2178       dist += len1 * len1;                                      \
       
  2179       len1 = double_lut[ 3 * k + 1 ] - col1;                    \
       
  2180       dist += len2 * len2;                                      \
       
  2181       len2 = double_lut[ 3 * k + 2 ] - col2;                    \
       
  2182       diff = ( mlib_s32 )dist - min_dist;                       \
       
  2183       mask = diff >> 31;                                        \
       
  2184       min_dist += diff & mask;                                  \
       
  2185       k_min += ( k - k_min ) & mask;                            \
       
  2186     }                                                           \
       
  2187                                                                 \
       
  2188     dst[ i ] = k_min + offset;                                  \
       
  2189   }
       
  2190 
       
  2191 /***************************************************************/
       
  2192 #define FIND_NEAREST_U8_4_C                                     \
       
  2193   mlib_s32 i, k, k_min, min_dist, diff, mask;                   \
       
  2194   mlib_s32 offset = mlib_ImageGetLutOffset( s ) - 1;            \
       
  2195   mlib_s32 entries = s -> lutlength;                            \
       
  2196   mlib_d64 *double_lut = mlib_ImageGetLutDoubleData( s );       \
       
  2197   mlib_d64 col0, col1, col2, col3;                              \
       
  2198   mlib_d64 dist, len0, len1, len2, len3;                        \
       
  2199                                                                 \
       
  2200   for ( i = 0; i < length; i++ ) {                              \
       
  2201     col0 = src[ 4 * i ];                                        \
       
  2202     col1 = src[ 4 * i + 1 ];                                    \
       
  2203     col2 = src[ 4 * i + 2 ];                                    \
       
  2204     col3 = src[ 4 * i + 3 ];                                    \
       
  2205     min_dist = MLIB_S32_MAX;                                    \
       
  2206     k_min = 1;                                                  \
       
  2207     len0 = double_lut[ 0 ] - col0;                              \
       
  2208     len1 = double_lut[ 1 ] - col1;                              \
       
  2209     len2 = double_lut[ 2 ] - col2;                              \
       
  2210     len3 = double_lut[ 3 ] - col3;                              \
       
  2211                                                                 \
       
  2212     for ( k = 1; k <= entries; k++ ) {                          \
       
  2213       dist = len0 * len0;                                       \
       
  2214       len0 =  double_lut[ 4 * k ] - col0;                       \
       
  2215       dist += len1 * len1;                                      \
       
  2216       len1 = double_lut[ 4 * k + 1 ] - col1;                    \
       
  2217       dist += len2 * len2;                                      \
       
  2218       len2 =  double_lut[ 4 * k + 2 ] - col2;                   \
       
  2219       dist += len3 * len3;                                      \
       
  2220       len3 =  double_lut[ 4 * k + 3 ] - col3;                   \
       
  2221       diff = ( mlib_s32 )dist - min_dist;                       \
       
  2222       mask = diff >> 31;                                        \
       
  2223       min_dist += diff & mask;                                  \
       
  2224       k_min += ( k - k_min ) & mask;                            \
       
  2225     }                                                           \
       
  2226                                                                 \
       
  2227     dst[ i ] = k_min + offset;                                  \
       
  2228   }
       
  2229 
       
  2230 /***************************************************************/
       
  2231 #define FSQR_S16_HI(dsrc)                                                   \
       
  2232   vis_fpadd32( vis_fmuld8ulx16( vis_read_hi( dsrc ), vis_read_hi( dsrc ) ), \
       
  2233     vis_fmuld8sux16( vis_read_hi( dsrc ), vis_read_hi( dsrc ) ) )
       
  2234 
       
  2235 /***************************************************************/
       
  2236 #define FSQR_S16_LO(dsrc)                                                  \
       
  2237   vis_fpadd32( vis_fmuld8ulx16( vis_read_lo( dsrc ), vis_read_lo( dsrc) ), \
       
  2238     vis_fmuld8sux16( vis_read_lo( dsrc ), vis_read_lo( dsrc ) ) )
       
  2239 
       
  2240 /***************************************************************/
       
  2241 #define FIND_NEAREST_U8_3                                             \
       
  2242 {                                                                     \
       
  2243   mlib_d64 *dpsrc, dsrc, dsrc1, ddist, ddist1, ddist2, ddist3;        \
       
  2244   mlib_d64 dcolor, dind, dres, dres1, dpind[1], dpmin[1];             \
       
  2245   mlib_d64 done = vis_to_double_dup( 1 ),                             \
       
  2246            dmax = vis_to_double_dup( MLIB_S32_MAX );                  \
       
  2247   mlib_f32 *lut = ( mlib_f32 * )mlib_ImageGetLutNormalTable( s );     \
       
  2248   mlib_f32 fone = vis_to_float( 0x100 );                              \
       
  2249   mlib_s32 i, k, mask;                                                \
       
  2250   mlib_s32 gsr[1];                                                    \
       
  2251   mlib_s32 offset = mlib_ImageGetLutOffset( s ) - 1;                  \
       
  2252   mlib_s32 entries = s->lutlength;                                    \
       
  2253                                                                       \
       
  2254   gsr[0] = vis_read_gsr();                                            \
       
  2255   for( i = 0; i <= ( length-2 ); i += 2 )                             \
       
  2256   {                                                                   \
       
  2257     dpsrc = VIS_ALIGNADDR( src, -1 );                                 \
       
  2258     src += 6;                                                         \
       
  2259     dsrc = dpsrc[ 0 ];                                                \
       
  2260     dsrc1 = dpsrc[ 1 ];                                               \
       
  2261     dsrc1 = vis_faligndata( dsrc, dsrc1 );                            \
       
  2262     dsrc = vis_fmul8x16al( vis_read_hi( dsrc1 ), fone );              \
       
  2263     VIS_ALIGNADDR( dpsrc, 3 );                                        \
       
  2264     dsrc1 = vis_faligndata( dsrc1, dsrc1 );                           \
       
  2265     dsrc1 = vis_fmul8x16al( vis_read_hi( dsrc1 ), fone );             \
       
  2266     dpind[ 0 ] = dind = done;                                         \
       
  2267     dpmin[ 0 ] = dmax;                                                \
       
  2268     dcolor = vis_fmul8x16al( lut[ 0 ], fone );                        \
       
  2269     for( k = 1; k <= entries; k++ )                                   \
       
  2270     {                                                                 \
       
  2271       ddist1 = vis_fpsub16( dcolor, dsrc );                           \
       
  2272       ddist = FSQR_S16_HI( ddist1 );                                  \
       
  2273       ddist1 = FSQR_S16_LO( ddist1 );                                 \
       
  2274       dres = vis_fpadd32( ddist, ddist1 );                            \
       
  2275       ddist3 = vis_fpsub16( dcolor, dsrc1 );                          \
       
  2276       ddist2 = FSQR_S16_HI( ddist3 );                                 \
       
  2277       ddist3 = FSQR_S16_LO( ddist3 );                                 \
       
  2278       dres1 = vis_fpadd32( ddist2, ddist3 );                          \
       
  2279       dcolor = vis_fmul8x16al( lut[ k ], fone );                      \
       
  2280       dres = vis_freg_pair(                                           \
       
  2281         vis_fpadd32s( vis_read_hi( dres ), vis_read_lo( dres ) ),     \
       
  2282         vis_fpadd32s( vis_read_hi( dres1 ), vis_read_lo( dres1 ) ) ); \
       
  2283       mask = vis_fcmplt32( dres, dpmin[ 0 ] );                        \
       
  2284       vis_pst_32( dind, ( void * )dpind, mask );                      \
       
  2285       dind = vis_fpadd32( dind, done );                               \
       
  2286       vis_pst_32( dres, ( void * )dpmin, mask );                      \
       
  2287     }                                                                 \
       
  2288     dst[ i ] = ( ( mlib_s32 * )dpind )[ 0 ] + offset;                 \
       
  2289     dst[ i + 1 ] = ( ( mlib_s32 * )dpind)[ 1 ] + offset;              \
       
  2290   }                                                                   \
       
  2291   if( i < length )                                                    \
       
  2292   {                                                                   \
       
  2293     dpsrc = VIS_ALIGNADDR( src, -1 );                                 \
       
  2294     dsrc = dpsrc[ 0 ];                                                \
       
  2295     dsrc1 = dpsrc[ 1 ];                                               \
       
  2296     dsrc1 = vis_faligndata( dsrc, dsrc1 );                            \
       
  2297     dsrc = vis_fmul8x16al( vis_read_hi( dsrc1 ), fone );              \
       
  2298     dpind[ 0 ] = dind = done;                                         \
       
  2299     dpmin[ 0 ] = dmax;                                                \
       
  2300     for( k = 0; k < entries; k++ )                                    \
       
  2301     {                                                                 \
       
  2302       dcolor = vis_fmul8x16al( lut[ k ], fone );                      \
       
  2303       ddist1 = vis_fpsub16( dcolor, dsrc );                           \
       
  2304       ddist = FSQR_S16_HI( ddist1 );                                  \
       
  2305       ddist1 = FSQR_S16_LO( ddist1 );                                 \
       
  2306       dres = vis_fpadd32( ddist, ddist1 );                            \
       
  2307       dres = vis_write_lo( dres,                                      \
       
  2308         vis_fpadd32s( vis_read_hi( dres ), vis_read_lo( dres ) ) );   \
       
  2309       mask = vis_fcmplt32( dres, dpmin[ 0 ] );                        \
       
  2310       vis_pst_32( dind, ( void * )dpind, mask );                      \
       
  2311       dind = vis_fpadd32( dind, done );                               \
       
  2312       vis_pst_32( dres, ( void * )dpmin, mask );                      \
       
  2313     }                                                                 \
       
  2314     dst[ i ] = ( ( mlib_s32 * )dpind)[ 1 ] + offset;                  \
       
  2315   }                                                                   \
       
  2316   vis_write_gsr(gsr[0]);                                              \
       
  2317 }
       
  2318 
       
  2319 /***************************************************************/
       
  2320 #define FIND_NEAREST_U8_3_IN4                                         \
       
  2321 {                                                                     \
       
  2322   mlib_d64 *dpsrc, dsrc, dsrc1, ddist, ddist1, ddist2, ddist3;        \
       
  2323   mlib_d64 dcolor, dind, dres, dres1, dpind[1], dpmin[1];             \
       
  2324   mlib_d64 done = vis_to_double_dup( 1 ),                             \
       
  2325            dmax = vis_to_double_dup( MLIB_S32_MAX );                  \
       
  2326   mlib_f32 *lut = ( mlib_f32 * )mlib_ImageGetLutNormalTable( s );     \
       
  2327   mlib_f32 fone = vis_to_float( 0x100 );                              \
       
  2328   mlib_s32 i, k, mask, gsr[1];                                        \
       
  2329   mlib_s32 offset = mlib_ImageGetLutOffset( s ) - 1;                  \
       
  2330   mlib_s32 entries = s->lutlength;                                    \
       
  2331                                                                       \
       
  2332   gsr[0] = vis_read_gsr();                                            \
       
  2333   dpsrc = VIS_ALIGNADDR( src, 0 );                                    \
       
  2334   for( i = 0; i <= ( length-2 ); i += 2 )                             \
       
  2335   {                                                                   \
       
  2336     dsrc = dpsrc[ 0 ];                                                \
       
  2337     dsrc1 = dpsrc[ 1 ];                                               \
       
  2338     dsrc1 = vis_faligndata( dsrc, dsrc1 );                            \
       
  2339     dpsrc++;                                                          \
       
  2340     dsrc = vis_fmul8x16al( vis_read_hi( dsrc1 ), fone );              \
       
  2341     dsrc1 = vis_fmul8x16al( vis_read_lo( dsrc1 ), fone );             \
       
  2342     dpind[ 0 ] = dind = done;                                         \
       
  2343     dpmin[ 0 ] = dmax;                                                \
       
  2344     dcolor = vis_fmul8x16al( lut[ 0 ], fone );                        \
       
  2345     for( k = 1; k <= entries; k++ )                                   \
       
  2346     {                                                                 \
       
  2347       ddist1 = vis_fpsub16( dcolor, dsrc );                           \
       
  2348       ddist = FSQR_S16_HI( ddist1 );                                  \
       
  2349       ddist1 = FSQR_S16_LO( ddist1 );                                 \
       
  2350       dres = vis_fpadd32( ddist, ddist1 );                            \
       
  2351       ddist3 = vis_fpsub16( dcolor, dsrc1 );                          \
       
  2352       ddist2 = FSQR_S16_HI( ddist3 );                                 \
       
  2353       ddist3 = FSQR_S16_LO( ddist3 );                                 \
       
  2354       dres1 = vis_fpadd32( ddist2, ddist3 );                          \
       
  2355       dcolor = vis_fmul8x16al( lut[ k ], fone );                      \
       
  2356       dres = vis_freg_pair(                                           \
       
  2357         vis_fpadd32s( vis_read_hi( dres ), vis_read_lo( dres ) ),     \
       
  2358         vis_fpadd32s( vis_read_hi( dres1 ), vis_read_lo( dres1 ) ) ); \
       
  2359       mask = vis_fcmplt32( dres, dpmin[ 0 ] );                        \
       
  2360       vis_pst_32( dind, ( void * )dpind, mask );                      \
       
  2361       dind = vis_fpadd32( dind, done );                               \
       
  2362       vis_pst_32( dres, ( void * )dpmin, mask );                      \
       
  2363     }                                                                 \
       
  2364     dst[ i ] = ( ( mlib_s32 * )dpind )[ 0 ] + offset;                 \
       
  2365     dst[ i + 1 ] = ( ( mlib_s32 * )dpind)[ 1 ] + offset;              \
       
  2366   }                                                                   \
       
  2367   if( i < length )                                                    \
       
  2368   {                                                                   \
       
  2369     dsrc = dpsrc[ 0 ];                                                \
       
  2370     dsrc1 = dpsrc[ 1 ];                                               \
       
  2371     dsrc1 = vis_faligndata( dsrc, dsrc1 );                            \
       
  2372     dsrc = vis_fmul8x16al( vis_read_hi( dsrc1 ), fone );              \
       
  2373     dpind[ 0 ] = dind = done;                                         \
       
  2374     dpmin[ 0 ] = dmax;                                                \
       
  2375     for( k = 0; k < entries; k++ )                                    \
       
  2376     {                                                                 \
       
  2377       dcolor = vis_fmul8x16al( lut[ k ], fone );                      \
       
  2378       ddist1 = vis_fpsub16( dcolor, dsrc );                           \
       
  2379       ddist = FSQR_S16_HI( ddist1 );                                  \
       
  2380       ddist1 = FSQR_S16_LO( ddist1 );                                 \
       
  2381       dres = vis_fpadd32( ddist, ddist1 );                            \
       
  2382       dres = vis_write_lo( dres,                                      \
       
  2383         vis_fpadd32s( vis_read_hi( dres ), vis_read_lo( dres ) ) );   \
       
  2384       mask = vis_fcmplt32( dres, dpmin[ 0 ] );                        \
       
  2385       vis_pst_32( dind, ( void * )dpind, mask );                      \
       
  2386       dind = vis_fpadd32( dind, done );                               \
       
  2387       vis_pst_32( dres, ( void * )dpmin, mask );                      \
       
  2388     }                                                                 \
       
  2389     dst[ i ] = ( ( mlib_s32 * )dpind)[ 1 ] + offset;                  \
       
  2390   }                                                                   \
       
  2391   vis_write_gsr(gsr[0]);                                              \
       
  2392 }
       
  2393 
       
  2394 /***************************************************************/
       
  2395 #define FIND_NEAREST_U8_4                                             \
       
  2396 {                                                                     \
       
  2397   mlib_d64 *dpsrc, dsrc, dsrc1, ddist, ddist1, ddist2, ddist3;        \
       
  2398   mlib_d64 dcolor, dind, dres, dres1, dpind[ 1 ], dpmin[ 1 ];         \
       
  2399   mlib_d64 done = vis_to_double_dup( 1 ),                             \
       
  2400            dmax = vis_to_double_dup( MLIB_S32_MAX );                  \
       
  2401   mlib_f32 *lut = ( mlib_f32 * )mlib_ImageGetLutNormalTable( s );     \
       
  2402   mlib_f32 fone = vis_to_float( 0x100 );                              \
       
  2403   mlib_s32 i, k, mask, gsr[1];                                        \
       
  2404   mlib_s32 offset = mlib_ImageGetLutOffset( s ) - 1;                  \
       
  2405   mlib_s32 entries = s->lutlength;                                    \
       
  2406                                                                       \
       
  2407   gsr[0] = vis_read_gsr();                                            \
       
  2408   dpsrc = VIS_ALIGNADDR( src, 0 );                                    \
       
  2409   for( i = 0; i <= ( length-2 ); i += 2 )                             \
       
  2410   {                                                                   \
       
  2411     dsrc = dpsrc[ 0 ];                                                \
       
  2412     dsrc1 = dpsrc[ 1 ];                                               \
       
  2413     dsrc1 = vis_faligndata( dsrc, dsrc1 );                            \
       
  2414     dpsrc++;                                                          \
       
  2415     dsrc = vis_fmul8x16al( vis_read_hi( dsrc1 ), fone );              \
       
  2416     dsrc1 = vis_fmul8x16al( vis_read_lo( dsrc1 ), fone );             \
       
  2417     dpind[ 0 ] = dind = done;                                         \
       
  2418     dpmin[ 0 ] = dmax;                                                \
       
  2419     dcolor = vis_fmul8x16al(lut[0], fone);                            \
       
  2420     for( k = 1; k <= entries; k++ )                                   \
       
  2421     {                                                                 \
       
  2422       ddist1 = vis_fpsub16( dcolor, dsrc );                           \
       
  2423       ddist = FSQR_S16_HI( ddist1 );                                  \
       
  2424       ddist1 = FSQR_S16_LO( ddist1 );                                 \
       
  2425       dres = vis_fpadd32( ddist, ddist1 );                            \
       
  2426       ddist3 = vis_fpsub16( dcolor, dsrc1 );                          \
       
  2427       ddist2 = FSQR_S16_HI( ddist3 );                                 \
       
  2428       ddist3 = FSQR_S16_LO( ddist3 );                                 \
       
  2429       dres1 = vis_fpadd32( ddist2, ddist3 );                          \
       
  2430       dcolor = vis_fmul8x16al( lut[ k ], fone );                      \
       
  2431       dres = vis_freg_pair(                                           \
       
  2432         vis_fpadd32s( vis_read_hi( dres ), vis_read_lo( dres ) ),     \
       
  2433         vis_fpadd32s( vis_read_hi( dres1 ), vis_read_lo( dres1 ) ) ); \
       
  2434       mask = vis_fcmplt32( dres, dpmin[ 0 ] );                        \
       
  2435       vis_pst_32( dind, ( void * )dpind, mask );                      \
       
  2436       dind = vis_fpadd32( dind, done );                               \
       
  2437       vis_pst_32( dres, ( void * )dpmin, mask );                      \
       
  2438     }                                                                 \
       
  2439     dst[ i ] = ( ( mlib_s32 * )dpind )[ 0 ] + offset;                 \
       
  2440     dst[ i + 1 ] = ( ( mlib_s32 * )dpind )[ 1 ] + offset;             \
       
  2441   }                                                                   \
       
  2442   if( i < length )                                                    \
       
  2443   {                                                                   \
       
  2444     dsrc = dpsrc[ 0 ];                                                \
       
  2445     dsrc1 = dpsrc[ 1 ];                                               \
       
  2446     dsrc1 = vis_faligndata( dsrc, dsrc1 );                            \
       
  2447     dsrc = vis_fmul8x16al( vis_read_hi( dsrc1 ), fone );              \
       
  2448     dpind[ 0 ] = dind = done;                                         \
       
  2449     dpmin[ 0 ] = dmax;                                                \
       
  2450     for( k = 0; k < entries; k++ )                                    \
       
  2451     {                                                                 \
       
  2452       dcolor = vis_fmul8x16al( lut[ k ], fone );                      \
       
  2453       ddist1 = vis_fpsub16( dcolor, dsrc );                           \
       
  2454       ddist = FSQR_S16_HI( ddist1 );                                  \
       
  2455       ddist1 = FSQR_S16_LO( ddist1 );                                 \
       
  2456       dres = vis_fpadd32( ddist, ddist1 );                            \
       
  2457       dres = vis_write_lo( dres,                                      \
       
  2458         vis_fpadd32s( vis_read_hi( dres ), vis_read_lo( dres ) ) );   \
       
  2459       mask = vis_fcmplt32( dres, dpmin[ 0 ] );                        \
       
  2460       vis_pst_32( dind, ( void * )dpind, mask );                      \
       
  2461       dind = vis_fpadd32( dind, done );                               \
       
  2462       vis_pst_32( dres, ( void * )dpmin, mask );                      \
       
  2463     }                                                                 \
       
  2464     dst[ i ] = ( ( mlib_s32 * )dpind )[ 1 ] + offset;                 \
       
  2465   }                                                                   \
       
  2466   vis_write_gsr(gsr[0]);                                              \
       
  2467 }
       
  2468 
       
  2469 /***************************************************************/
       
  2470 #define FIND_NEAREST_S16_3( SHIFT, STEP )                       \
       
  2471   mlib_s32 i, k, k_min, min_dist, diff, mask;                   \
       
  2472   mlib_s32 offset = mlib_ImageGetLutOffset( s ) - 1;            \
       
  2473   mlib_s32 entries = s->lutlength;                              \
       
  2474   mlib_d64 *double_lut = mlib_ImageGetLutDoubleData( s );       \
       
  2475   mlib_d64 col0, col1, col2;                                    \
       
  2476   mlib_d64 dist, len0, len1, len2;                              \
       
  2477                                                                 \
       
  2478   for( i = 0; i < length; i++ )                                 \
       
  2479   {                                                             \
       
  2480     col0 = src[ STEP * i + SHIFT ];                             \
       
  2481     col1 = src[ STEP * i + 1 + SHIFT ];                         \
       
  2482     col2 = src[ STEP * i + 2 + SHIFT ];                         \
       
  2483     min_dist = MLIB_S32_MAX;                                    \
       
  2484     k_min = 1;                                                  \
       
  2485     len0 = double_lut[ 0 ] - col0;                              \
       
  2486     len1 = double_lut[ 1 ] - col1;                              \
       
  2487     len2 = double_lut[ 2 ] - col2;                              \
       
  2488     for( k = 1; k <= entries; k++ )                             \
       
  2489     {                                                           \
       
  2490       dist = len0 * len0;                                       \
       
  2491       len0 = double_lut[ 3 * k ] - col0;                        \
       
  2492       dist += len1 * len1;                                      \
       
  2493       len1 = double_lut[ 3 * k + 1 ] - col1;                    \
       
  2494       dist += len2 * len2;                                      \
       
  2495       len2 = double_lut[ 3 * k + 2 ] - col2;                    \
       
  2496       diff = ( mlib_s32 )( dist * 0.125 ) - min_dist;           \
       
  2497       mask = diff >> 31;                                        \
       
  2498       min_dist += diff & mask;                                  \
       
  2499       k_min += ( k - k_min ) & mask;                            \
       
  2500     }                                                           \
       
  2501     dst[ i ] = k_min + offset;                                  \
       
  2502   }
       
  2503 
       
  2504 /***************************************************************/
       
  2505 #define FIND_NEAREST_S16_4                                      \
       
  2506   mlib_s32 i, k, k_min, min_dist, diff, mask;                   \
       
  2507   mlib_s32 offset = mlib_ImageGetLutOffset( s ) - 1;            \
       
  2508   mlib_s32 entries = s->lutlength;                              \
       
  2509   mlib_d64 *double_lut = mlib_ImageGetLutDoubleData( s );       \
       
  2510   mlib_d64 col0, col1, col2, col3;                              \
       
  2511   mlib_d64 dist, len0, len1, len2, len3;                        \
       
  2512                                                                 \
       
  2513   for( i = 0; i < length; i++ )                                 \
       
  2514   {                                                             \
       
  2515     col0 = src[ 4 * i ];                                        \
       
  2516     col1 = src[ 4 * i + 1 ];                                    \
       
  2517     col2 = src[ 4 * i + 2 ];                                    \
       
  2518     col3 = src[ 4 * i + 3 ];                                    \
       
  2519     min_dist = MLIB_S32_MAX;                                    \
       
  2520     k_min = 1;                                                  \
       
  2521     len0 = double_lut[ 0 ] - col0;                              \
       
  2522     len1 = double_lut[ 1 ] - col1;                              \
       
  2523     len2 = double_lut[ 2 ] - col2;                              \
       
  2524     len3 = double_lut[ 3 ] - col3;                              \
       
  2525     for( k = 1; k <= entries; k++ )                             \
       
  2526     {                                                           \
       
  2527       dist = len0 * len0;                                       \
       
  2528       len0 =  double_lut[ 4 * k ] - col0;                       \
       
  2529       dist += len1 * len1;                                      \
       
  2530       len1 = double_lut[ 4 * k + 1 ] - col1;                    \
       
  2531       dist += len2 * len2;                                      \
       
  2532       len2 =  double_lut[ 4 * k + 2 ] - col2;                   \
       
  2533       dist += len3 * len3;                                      \
       
  2534       len3 =  double_lut[ 4 * k + 3 ] - col3;                   \
       
  2535       diff = ( mlib_s32 )( dist * 0.125 ) - min_dist;           \
       
  2536       mask = diff >> 31;                                        \
       
  2537       min_dist += diff & mask;                                  \
       
  2538       k_min += ( k - k_min ) & mask;                            \
       
  2539     }                                                           \
       
  2540     dst[ i ] = k_min + offset;                                  \
       
  2541   }
       
  2542 
       
  2543 /***************************************************************/
       
  2544 mlib_status mlib_ImageColorTrue2Index(mlib_image       *dst,
       
  2545                                       const mlib_image *src,
       
  2546                                       const void       *colormap)
       
  2547 {
       
  2548   mlib_s32 y, width, height, sstride, dstride, schann;
       
  2549   mlib_colormap *s = (mlib_colormap *)colormap;
       
  2550   mlib_s32 channels;
       
  2551   mlib_type stype, dtype;
       
  2552 
       
  2553   MLIB_IMAGE_CHECK(src);
       
  2554   MLIB_IMAGE_CHECK(dst);
       
  2555   MLIB_IMAGE_SIZE_EQUAL(src, dst);
       
  2556   MLIB_IMAGE_HAVE_CHAN(dst, 1);
       
  2557 
       
  2558   if (!colormap)
       
  2559     return MLIB_NULLPOINTER;
       
  2560 
       
  2561   channels = s->channels;
       
  2562   stype = mlib_ImageGetType(src);
       
  2563   dtype = mlib_ImageGetType(dst);
       
  2564   width = mlib_ImageGetWidth(src);
       
  2565   height = mlib_ImageGetHeight(src);
       
  2566   sstride = mlib_ImageGetStride(src);
       
  2567   dstride = mlib_ImageGetStride(dst);
       
  2568   schann = mlib_ImageGetChannels(src);
       
  2569 
       
  2570   if (stype != s->intype || dtype != s->outtype)
       
  2571     return MLIB_FAILURE;
       
  2572 
       
  2573   if (channels != schann)
       
  2574     return MLIB_FAILURE;
       
  2575 
       
  2576   switch (stype) {
       
  2577     case MLIB_BYTE:
       
  2578       {
       
  2579         mlib_u8 *sdata = mlib_ImageGetData(src);
       
  2580 
       
  2581         switch (dtype) {
       
  2582           case MLIB_BYTE:
       
  2583             {
       
  2584               mlib_u8 *ddata = mlib_ImageGetData(dst);
       
  2585 
       
  2586               switch (channels) {
       
  2587                 case 3:
       
  2588                   {
       
  2589                     MAIN_COLORTRUE2INDEX_LOOP(U8, U8, 3);
       
  2590                     return MLIB_SUCCESS;
       
  2591                   }
       
  2592 
       
  2593                 case 4:
       
  2594                   {
       
  2595                     MAIN_COLORTRUE2INDEX_LOOP(U8, U8, 4);
       
  2596                     return MLIB_SUCCESS;
       
  2597                   }
       
  2598 
       
  2599                 default:
       
  2600                   return MLIB_FAILURE;
       
  2601               }
       
  2602             }
       
  2603 
       
  2604           case MLIB_SHORT:
       
  2605             {
       
  2606               mlib_s16 *ddata = mlib_ImageGetData(dst);
       
  2607 
       
  2608               dstride /= 2;
       
  2609               switch (channels) {
       
  2610                 case 3:
       
  2611                   {
       
  2612                     MAIN_COLORTRUE2INDEX_LOOP(U8, S16, 3);
       
  2613                     return MLIB_SUCCESS;
       
  2614                   }
       
  2615 
       
  2616                 case 4:
       
  2617                   {
       
  2618                     MAIN_COLORTRUE2INDEX_LOOP(U8, S16, 4);
       
  2619                     return MLIB_SUCCESS;
       
  2620                   }
       
  2621 
       
  2622                 default:
       
  2623                   return MLIB_FAILURE;
       
  2624               }
       
  2625             }
       
  2626         default:
       
  2627           /* Unsupported type of destination image */
       
  2628           return MLIB_FAILURE;
       
  2629         }
       
  2630       }
       
  2631 
       
  2632     case MLIB_SHORT:
       
  2633       {
       
  2634         mlib_s16 *sdata = mlib_ImageGetData(src);
       
  2635 
       
  2636         sstride /= 2;
       
  2637         switch (dtype) {
       
  2638           case MLIB_BYTE:
       
  2639             {
       
  2640               mlib_u8 *ddata = mlib_ImageGetData(dst);
       
  2641 
       
  2642               switch (channels) {
       
  2643                 case 3:
       
  2644                   {
       
  2645                     MAIN_COLORTRUE2INDEX_LOOP(S16, U8, 3);
       
  2646                     return MLIB_SUCCESS;
       
  2647                   }
       
  2648 
       
  2649                 case 4:
       
  2650                   {
       
  2651                     MAIN_COLORTRUE2INDEX_LOOP(S16, U8, 4);
       
  2652                     return MLIB_SUCCESS;
       
  2653                   }
       
  2654 
       
  2655                 default:
       
  2656                   return MLIB_FAILURE;
       
  2657               }
       
  2658             }
       
  2659 
       
  2660           case MLIB_SHORT:
       
  2661             {
       
  2662               mlib_s16 *ddata = mlib_ImageGetData(dst);
       
  2663 
       
  2664               dstride /= 2;
       
  2665               switch (channels) {
       
  2666                 case 3:
       
  2667                   {
       
  2668                     MAIN_COLORTRUE2INDEX_LOOP(S16, S16, 3);
       
  2669                     return MLIB_SUCCESS;
       
  2670                   }
       
  2671 
       
  2672                 case 4:
       
  2673                   {
       
  2674                     MAIN_COLORTRUE2INDEX_LOOP(S16, S16, 4);
       
  2675                     return MLIB_SUCCESS;
       
  2676                   }
       
  2677 
       
  2678                 default:
       
  2679                   return MLIB_FAILURE;
       
  2680               }
       
  2681             }
       
  2682         default:
       
  2683           /* Unsupported type of destination image */
       
  2684           return MLIB_FAILURE;
       
  2685         }
       
  2686       }
       
  2687 
       
  2688     default:
       
  2689       return MLIB_FAILURE;
       
  2690   }
       
  2691 }
       
  2692 
       
  2693 /***************************************************************/
       
  2694 mlib_u32 mlib_search_quadrant_U8_3(struct lut_node_3 *node,
       
  2695                                    mlib_u32          distance,
       
  2696                                     mlib_s32    *found_color,
       
  2697                                    mlib_u32          c0,
       
  2698                                    mlib_u32          c1,
       
  2699                                    mlib_u32          c2,
       
  2700                                    const mlib_u8     **base)
       
  2701 {
       
  2702   mlib_s32 i;
       
  2703 
       
  2704   for (i = 0; i < 8; i++) {
       
  2705 
       
  2706     if (node->tag & (1 << i)) {
       
  2707       /* Here is alone color cell. Check the distance */
       
  2708       mlib_s32 newindex = node->contents.index[i];
       
  2709       mlib_u32 newpalc0, newpalc1, newpalc2;
       
  2710       mlib_u32 newdistance;
       
  2711 
       
  2712       newpalc0 = base[0][newindex];
       
  2713       newpalc1 = base[1][newindex];
       
  2714       newpalc2 = base[2][newindex];
       
  2715       newdistance = FIND_DISTANCE_3(c0, newpalc0, c1, newpalc1, c2, newpalc2, 0);
       
  2716 
       
  2717       if (distance > newdistance) {
       
  2718         *found_color = newindex;
       
  2719         distance = newdistance;
       
  2720       }
       
  2721     }
       
  2722     else if (node->contents.quadrants[i])
       
  2723       distance =
       
  2724         mlib_search_quadrant_U8_3(node->contents.quadrants[i], distance,
       
  2725                                   found_color, c0, c1, c2, base);
       
  2726   }
       
  2727 
       
  2728   return distance;
       
  2729 }
       
  2730 
       
  2731 /***************************************************************/
       
  2732 mlib_u32 mlib_search_quadrant_part_to_left_U8_3(struct lut_node_3 *node,
       
  2733                                                 mlib_u32          distance,
       
  2734                                                  mlib_s32    *found_color,
       
  2735                                                 const mlib_u32    *c,
       
  2736                                                 const mlib_u8     **base,
       
  2737                                                 mlib_u32          position,
       
  2738                                                 mlib_s32          pass,
       
  2739                                                 mlib_s32          dir_bit)
       
  2740 {
       
  2741   mlib_u32 current_size = 1 << pass;
       
  2742   mlib_s32 i;
       
  2743   static mlib_s32 opposite_quadrants[3][4] = {
       
  2744     {0, 2, 4, 6},
       
  2745     {0, 1, 4, 5},
       
  2746     {0, 1, 2, 3}
       
  2747   };
       
  2748 
       
  2749 /* Search only quadrant's half untill it is necessary to check the
       
  2750   whole quadrant */
       
  2751 
       
  2752   if (distance < (position + current_size - c[dir_bit]) * (position + current_size - c[dir_bit])) { /* Search half of quadrant */
       
  2753     for (i = 0; i < 4; i++) {
       
  2754       mlib_s32 qq = opposite_quadrants[dir_bit][i];
       
  2755 
       
  2756       if (node->tag & (1 << qq)) {
       
  2757         /* Here is alone color cell. Check the distance */
       
  2758         mlib_s32 newindex = node->contents.index[qq];
       
  2759         mlib_u32 newpalc0, newpalc1, newpalc2;
       
  2760         mlib_u32 newdistance;
       
  2761 
       
  2762         newpalc0 = base[0][newindex];
       
  2763         newpalc1 = base[1][newindex];
       
  2764         newpalc2 = base[2][newindex];
       
  2765         newdistance = FIND_DISTANCE_3(c[0], newpalc0, c[1], newpalc1, c[2], newpalc2, 0);
       
  2766 
       
  2767         if (distance > newdistance) {
       
  2768           *found_color = newindex;
       
  2769           distance = newdistance;
       
  2770         }
       
  2771       }
       
  2772       else if (node->contents.quadrants[qq])
       
  2773         distance =
       
  2774           mlib_search_quadrant_part_to_left_U8_3(node->contents.quadrants[qq],
       
  2775                                                  distance, found_color, c, base,
       
  2776                                                  position, pass - 1, dir_bit);
       
  2777     }
       
  2778   }
       
  2779   else {                                    /* Search whole quadrant */
       
  2780 
       
  2781     mlib_s32 mask = 1 << dir_bit;
       
  2782 
       
  2783     for (i = 0; i < 8; i++) {
       
  2784 
       
  2785       if (node->tag & (1 << i)) {
       
  2786         /* Here is alone color cell. Check the distance */
       
  2787         mlib_s32 newindex = node->contents.index[i];
       
  2788         mlib_u32 newpalc0, newpalc1, newpalc2;
       
  2789         mlib_u32 newdistance;
       
  2790 
       
  2791         newpalc0 = base[0][newindex];
       
  2792         newpalc1 = base[1][newindex];
       
  2793         newpalc2 = base[2][newindex];
       
  2794         newdistance = FIND_DISTANCE_3(c[0], newpalc0, c[1], newpalc1, c[2], newpalc2, 0);
       
  2795 
       
  2796         if (distance > newdistance) {
       
  2797           *found_color = newindex;
       
  2798           distance = newdistance;
       
  2799         }
       
  2800       }
       
  2801       else if (node->contents.quadrants[i]) {
       
  2802 
       
  2803         if (i & mask)
       
  2804           /* This quadrant may require partial checking */
       
  2805           distance =
       
  2806             mlib_search_quadrant_part_to_left_U8_3(node->contents.quadrants[i],
       
  2807                                                    distance, found_color, c,
       
  2808                                                    base,
       
  2809                                                    position + current_size,
       
  2810                                                    pass - 1, dir_bit);
       
  2811         else
       
  2812           /* Here we should check all */
       
  2813           distance =
       
  2814             mlib_search_quadrant_U8_3(node->contents.quadrants[i], distance,
       
  2815                                       found_color, c[0], c[1], c[2], base);
       
  2816       }
       
  2817     }
       
  2818   }
       
  2819 
       
  2820   return distance;
       
  2821 }
       
  2822 
       
  2823 /***************************************************************/
       
  2824 mlib_u32 mlib_search_quadrant_part_to_right_U8_3(struct lut_node_3 *node,
       
  2825                                                  mlib_u32          distance,
       
  2826                                                   mlib_s32    *found_color,
       
  2827                                                  const mlib_u32    *c,
       
  2828                                                  const mlib_u8     **base,
       
  2829                                                  mlib_u32          position,
       
  2830                                                  mlib_s32          pass,
       
  2831                                                  mlib_s32          dir_bit)
       
  2832 {
       
  2833   mlib_u32 current_size = 1 << pass;
       
  2834   mlib_s32 i;
       
  2835   static mlib_s32 opposite_quadrants[3][4] = {
       
  2836     {1, 3, 5, 7},
       
  2837     {2, 3, 6, 7},
       
  2838     {4, 5, 6, 7}
       
  2839   };
       
  2840 
       
  2841 /* Search only quadrant's half untill it is necessary to check the
       
  2842   whole quadrant */
       
  2843 
       
  2844   if (distance <= (c[dir_bit] - position - current_size) * (c[dir_bit] - position - current_size)) { /* Search half of quadrant */
       
  2845     for (i = 0; i < 4; i++) {
       
  2846       mlib_s32 qq = opposite_quadrants[dir_bit][i];
       
  2847 
       
  2848       if (node->tag & (1 << qq)) {
       
  2849         /* Here is alone color cell. Check the distance */
       
  2850         mlib_s32 newindex = node->contents.index[qq];
       
  2851         mlib_u32 newpalc0, newpalc1, newpalc2;
       
  2852         mlib_u32 newdistance;
       
  2853 
       
  2854         newpalc0 = base[0][newindex];
       
  2855         newpalc1 = base[1][newindex];
       
  2856         newpalc2 = base[2][newindex];
       
  2857         newdistance = FIND_DISTANCE_3(c[0], newpalc0, c[1], newpalc1, c[2], newpalc2, 0);
       
  2858 
       
  2859         if (distance > newdistance) {
       
  2860           *found_color = newindex;
       
  2861           distance = newdistance;
       
  2862         }
       
  2863       }
       
  2864       else if (node->contents.quadrants[qq])
       
  2865         distance =
       
  2866           mlib_search_quadrant_part_to_right_U8_3(node->contents.quadrants[qq],
       
  2867                                                   distance, found_color, c,
       
  2868                                                   base, position + current_size,
       
  2869                                                   pass - 1, dir_bit);
       
  2870     }
       
  2871   }
       
  2872   else {                                    /* Search whole quadrant */
       
  2873 
       
  2874     mlib_s32 mask = 1 << dir_bit;
       
  2875 
       
  2876     for (i = 0; i < 8; i++) {
       
  2877 
       
  2878       if (node->tag & (1 << i)) {
       
  2879         /* Here is alone color cell. Check the distance */
       
  2880         mlib_s32 newindex = node->contents.index[i];
       
  2881         mlib_u32 newpalc0, newpalc1, newpalc2;
       
  2882         mlib_u32 newdistance;
       
  2883 
       
  2884         newpalc0 = base[0][newindex];
       
  2885         newpalc1 = base[1][newindex];
       
  2886         newpalc2 = base[2][newindex];
       
  2887         newdistance = FIND_DISTANCE_3(c[0], newpalc0, c[1], newpalc1, c[2], newpalc2, 0);
       
  2888 
       
  2889         if (distance > newdistance) {
       
  2890           *found_color = newindex;
       
  2891           distance = newdistance;
       
  2892         }
       
  2893       }
       
  2894       else if (node->contents.quadrants[i]) {
       
  2895 
       
  2896         if (i & mask)
       
  2897           /* Here we should check all */
       
  2898           distance =
       
  2899             mlib_search_quadrant_U8_3(node->contents.quadrants[i], distance,
       
  2900                                       found_color, c[0], c[1], c[2], base);
       
  2901         else
       
  2902           /* This quadrant may require partial checking */
       
  2903           distance =
       
  2904             mlib_search_quadrant_part_to_right_U8_3(node->contents.quadrants[i],
       
  2905                                                     distance, found_color, c,
       
  2906                                                     base, position, pass - 1, dir_bit);
       
  2907       }
       
  2908     }
       
  2909   }
       
  2910 
       
  2911   return distance;
       
  2912 }
       
  2913 
       
  2914 /***************************************************************/
       
  2915 mlib_u32 mlib_search_quadrant_S16_3(struct lut_node_3 *node,
       
  2916                                     mlib_u32          distance,
       
  2917                                      mlib_s32    *found_color,
       
  2918                                     mlib_u32          c0,
       
  2919                                     mlib_u32          c1,
       
  2920                                     mlib_u32          c2,
       
  2921                                     const mlib_s16    **base)
       
  2922 {
       
  2923   mlib_s32 i;
       
  2924 
       
  2925   for (i = 0; i < 8; i++) {
       
  2926 
       
  2927     if (node->tag & (1 << i)) {
       
  2928       /* Here is alone color cell. Check the distance */
       
  2929       mlib_s32 newindex = node->contents.index[i];
       
  2930       mlib_u32 newpalc0, newpalc1, newpalc2;
       
  2931       mlib_u32 newdistance;
       
  2932 
       
  2933       newpalc0 = base[0][newindex] - MLIB_S16_MIN;
       
  2934       newpalc1 = base[1][newindex] - MLIB_S16_MIN;
       
  2935       newpalc2 = base[2][newindex] - MLIB_S16_MIN;
       
  2936       newdistance = FIND_DISTANCE_3(c0, newpalc0, c1, newpalc1, c2, newpalc2, 2);
       
  2937 
       
  2938       if (distance > newdistance) {
       
  2939         *found_color = newindex;
       
  2940         distance = newdistance;
       
  2941       }
       
  2942     }
       
  2943     else if (node->contents.quadrants[i])
       
  2944       distance =
       
  2945         mlib_search_quadrant_S16_3(node->contents.quadrants[i], distance,
       
  2946                                    found_color, c0, c1, c2, base);
       
  2947   }
       
  2948 
       
  2949   return distance;
       
  2950 }
       
  2951 
       
  2952 /***************************************************************/
       
  2953 mlib_u32 mlib_search_quadrant_part_to_left_S16_3(struct lut_node_3 *node,
       
  2954                                                  mlib_u32          distance,
       
  2955                                                   mlib_s32    *found_color,
       
  2956                                                  const mlib_u32    *c,
       
  2957                                                  const mlib_s16    **base,
       
  2958                                                  mlib_u32          position,
       
  2959                                                  mlib_s32          pass,
       
  2960                                                  mlib_s32          dir_bit)
       
  2961 {
       
  2962   mlib_u32 current_size = 1 << pass;
       
  2963   mlib_s32 i;
       
  2964   static mlib_s32 opposite_quadrants[3][4] = {
       
  2965     {0, 2, 4, 6},
       
  2966     {0, 1, 4, 5},
       
  2967     {0, 1, 2, 3}
       
  2968   };
       
  2969 
       
  2970 /* Search only quadrant's half untill it is necessary to check the
       
  2971   whole quadrant */
       
  2972 
       
  2973   if (distance < (((position + current_size - c[dir_bit]) * (position + current_size - c[dir_bit])) >> 2)) { /* Search half of quadrant */
       
  2974     for (i = 0; i < 4; i++) {
       
  2975       mlib_s32 qq = opposite_quadrants[dir_bit][i];
       
  2976 
       
  2977       if (node->tag & (1 << qq)) {
       
  2978         /* Here is alone color cell. Check the distance */
       
  2979         mlib_s32 newindex = node->contents.index[qq];
       
  2980         mlib_u32 newpalc0, newpalc1, newpalc2;
       
  2981         mlib_u32 newdistance;
       
  2982 
       
  2983         newpalc0 = base[0][newindex] - MLIB_S16_MIN;
       
  2984         newpalc1 = base[1][newindex] - MLIB_S16_MIN;
       
  2985         newpalc2 = base[2][newindex] - MLIB_S16_MIN;
       
  2986         newdistance = FIND_DISTANCE_3(c[0], newpalc0, c[1], newpalc1, c[2], newpalc2, 2);
       
  2987 
       
  2988         if (distance > newdistance) {
       
  2989           *found_color = newindex;
       
  2990           distance = newdistance;
       
  2991         }
       
  2992       }
       
  2993       else if (node->contents.quadrants[qq])
       
  2994         distance =
       
  2995           mlib_search_quadrant_part_to_left_S16_3(node->contents.quadrants[qq],
       
  2996                                                   distance, found_color, c,
       
  2997                                                   base, position, pass - 1, dir_bit);
       
  2998     }
       
  2999   }
       
  3000   else {                                    /* Search whole quadrant */
       
  3001 
       
  3002     mlib_s32 mask = 1 << dir_bit;
       
  3003 
       
  3004     for (i = 0; i < 8; i++) {
       
  3005 
       
  3006       if (node->tag & (1 << i)) {
       
  3007         /* Here is alone color cell. Check the distance */
       
  3008         mlib_s32 newindex = node->contents.index[i];
       
  3009         mlib_u32 newpalc0, newpalc1, newpalc2;
       
  3010         mlib_u32 newdistance;
       
  3011 
       
  3012         newpalc0 = base[0][newindex] - MLIB_S16_MIN;
       
  3013         newpalc1 = base[1][newindex] - MLIB_S16_MIN;
       
  3014         newpalc2 = base[2][newindex] - MLIB_S16_MIN;
       
  3015         newdistance = FIND_DISTANCE_3(c[0], newpalc0, c[1], newpalc1, c[2], newpalc2, 2);
       
  3016 
       
  3017         if (distance > newdistance) {
       
  3018           *found_color = newindex;
       
  3019           distance = newdistance;
       
  3020         }
       
  3021       }
       
  3022       else if (node->contents.quadrants[i]) {
       
  3023 
       
  3024         if (i & mask)
       
  3025           /* This quadrant may require partial checking */
       
  3026           distance =
       
  3027             mlib_search_quadrant_part_to_left_S16_3(node->contents.quadrants[i],
       
  3028                                                     distance, found_color, c,
       
  3029                                                     base,
       
  3030                                                     position + current_size,
       
  3031                                                     pass - 1, dir_bit);
       
  3032         else
       
  3033           /* Here we should check all */
       
  3034           distance =
       
  3035             mlib_search_quadrant_S16_3(node->contents.quadrants[i], distance,
       
  3036                                        found_color, c[0], c[1], c[2], base);
       
  3037       }
       
  3038     }
       
  3039   }
       
  3040 
       
  3041   return distance;
       
  3042 }
       
  3043 
       
  3044 /***************************************************************/
       
  3045 mlib_u32 mlib_search_quadrant_part_to_right_S16_3(struct lut_node_3 *node,
       
  3046                                                   mlib_u32          distance,
       
  3047                                                    mlib_s32    *found_color,
       
  3048                                                   const mlib_u32    *c,
       
  3049                                                   const mlib_s16    **base,
       
  3050                                                   mlib_u32          position,
       
  3051                                                   mlib_s32          pass,
       
  3052                                                   mlib_s32          dir_bit)
       
  3053 {
       
  3054   mlib_u32 current_size = 1 << pass;
       
  3055   mlib_s32 i;
       
  3056   static mlib_s32 opposite_quadrants[3][4] = {
       
  3057     {1, 3, 5, 7},
       
  3058     {2, 3, 6, 7},
       
  3059     {4, 5, 6, 7}
       
  3060   };
       
  3061 
       
  3062 /* Search only quadrant's half untill it is necessary to check the
       
  3063   whole quadrant */
       
  3064 
       
  3065   if (distance <= (((c[dir_bit] - position - current_size) * (c[dir_bit] - position - current_size)) >> 2)) { /* Search half of quadrant */
       
  3066     for (i = 0; i < 4; i++) {
       
  3067       mlib_s32 qq = opposite_quadrants[dir_bit][i];
       
  3068 
       
  3069       if (node->tag & (1 << qq)) {
       
  3070         /* Here is alone color cell. Check the distance */
       
  3071         mlib_s32 newindex = node->contents.index[qq];
       
  3072         mlib_u32 newpalc0, newpalc1, newpalc2;
       
  3073         mlib_u32 newdistance;
       
  3074 
       
  3075         newpalc0 = base[0][newindex] - MLIB_S16_MIN;
       
  3076         newpalc1 = base[1][newindex] - MLIB_S16_MIN;
       
  3077         newpalc2 = base[2][newindex] - MLIB_S16_MIN;
       
  3078         newdistance = FIND_DISTANCE_3(c[0], newpalc0, c[1], newpalc1, c[2], newpalc2, 2);
       
  3079 
       
  3080         if (distance > newdistance) {
       
  3081           *found_color = newindex;
       
  3082           distance = newdistance;
       
  3083         }
       
  3084       }
       
  3085       else if (node->contents.quadrants[qq])
       
  3086         distance =
       
  3087           mlib_search_quadrant_part_to_right_S16_3(node->contents.quadrants[qq],
       
  3088                                                    distance, found_color, c,
       
  3089                                                    base,
       
  3090                                                    position + current_size,
       
  3091                                                    pass - 1, dir_bit);
       
  3092     }
       
  3093   }
       
  3094   else {                                    /* Search whole quadrant */
       
  3095 
       
  3096     mlib_s32 mask = 1 << dir_bit;
       
  3097 
       
  3098     for (i = 0; i < 8; i++) {
       
  3099 
       
  3100       if (node->tag & (1 << i)) {
       
  3101         /* Here is alone color cell. Check the distance */
       
  3102         mlib_s32 newindex = node->contents.index[i];
       
  3103         mlib_u32 newpalc0, newpalc1, newpalc2;
       
  3104         mlib_u32 newdistance;
       
  3105 
       
  3106         newpalc0 = base[0][newindex] - MLIB_S16_MIN;
       
  3107         newpalc1 = base[1][newindex] - MLIB_S16_MIN;
       
  3108         newpalc2 = base[2][newindex] - MLIB_S16_MIN;
       
  3109         newdistance = FIND_DISTANCE_3(c[0], newpalc0, c[1], newpalc1, c[2], newpalc2, 2);
       
  3110 
       
  3111         if (distance > newdistance) {
       
  3112           *found_color = newindex;
       
  3113           distance = newdistance;
       
  3114         }
       
  3115       }
       
  3116       else if (node->contents.quadrants[i]) {
       
  3117 
       
  3118         if (i & mask)
       
  3119           /* Here we should check all */
       
  3120           distance =
       
  3121             mlib_search_quadrant_S16_3(node->contents.quadrants[i], distance,
       
  3122                                        found_color, c[0], c[1], c[2], base);
       
  3123         else
       
  3124           /* This quadrant may require partial checking */
       
  3125           distance =
       
  3126             mlib_search_quadrant_part_to_right_S16_3(node->contents.
       
  3127                                                      quadrants[i], distance,
       
  3128                                                      found_color, c, base,
       
  3129                                                      position, pass - 1, dir_bit);
       
  3130       }
       
  3131     }
       
  3132   }
       
  3133 
       
  3134   return distance;
       
  3135 }
       
  3136 
       
  3137 /***************************************************************/
       
  3138 mlib_u32 mlib_search_quadrant_U8_4(struct lut_node_4 *node,
       
  3139                                    mlib_u32          distance,
       
  3140                                     mlib_s32    *found_color,
       
  3141                                    mlib_u32          c0,
       
  3142                                    mlib_u32          c1,
       
  3143                                    mlib_u32          c2,
       
  3144                                    mlib_u32          c3,
       
  3145                                    const mlib_u8     **base)
       
  3146 {
       
  3147   mlib_s32 i;
       
  3148 
       
  3149   for (i = 0; i < 16; i++) {
       
  3150 
       
  3151     if (node->tag & (1 << i)) {
       
  3152       /* Here is alone color cell. Check the distance */
       
  3153       mlib_s32 newindex = node->contents.index[i];
       
  3154       mlib_u32 newpalc0, newpalc1, newpalc2, newpalc3;
       
  3155       mlib_u32 newdistance;
       
  3156 
       
  3157       newpalc0 = base[0][newindex];
       
  3158       newpalc1 = base[1][newindex];
       
  3159       newpalc2 = base[2][newindex];
       
  3160       newpalc3 = base[3][newindex];
       
  3161       newdistance = FIND_DISTANCE_4(c0, newpalc0,
       
  3162                                     c1, newpalc1, c2, newpalc2, c3, newpalc3, 0);
       
  3163 
       
  3164       if (distance > newdistance) {
       
  3165         *found_color = newindex;
       
  3166         distance = newdistance;
       
  3167       }
       
  3168     }
       
  3169     else if (node->contents.quadrants[i])
       
  3170       distance =
       
  3171         mlib_search_quadrant_U8_4(node->contents.quadrants[i], distance,
       
  3172                                   found_color, c0, c1, c2, c3, base);
       
  3173   }
       
  3174 
       
  3175   return distance;
       
  3176 }
       
  3177 
       
  3178 /***************************************************************/
       
  3179 mlib_u32 mlib_search_quadrant_part_to_left_U8_4(struct lut_node_4 *node,
       
  3180                                                 mlib_u32          distance,
       
  3181                                                  mlib_s32    *found_color,
       
  3182                                                 const mlib_u32    *c,
       
  3183                                                 const mlib_u8     **base,
       
  3184                                                 mlib_u32          position,
       
  3185                                                 mlib_s32          pass,
       
  3186                                                 mlib_s32          dir_bit)
       
  3187 {
       
  3188   mlib_u32 current_size = 1 << pass;
       
  3189   mlib_s32 i;
       
  3190   static mlib_s32 opposite_quadrants[4][8] = {
       
  3191     {0, 2, 4, 6, 8, 10, 12, 14},
       
  3192     {0, 1, 4, 5, 8, 9, 12, 13},
       
  3193     {0, 1, 2, 3, 8, 9, 10, 11},
       
  3194     {0, 1, 2, 3, 4, 5, 6, 7}
       
  3195   };
       
  3196 
       
  3197 /* Search only quadrant's half untill it is necessary to check the
       
  3198   whole quadrant */
       
  3199 
       
  3200   if (distance < (position + current_size - c[dir_bit]) * (position + current_size - c[dir_bit])) { /* Search half of quadrant */
       
  3201     for (i = 0; i < 8; i++) {
       
  3202       mlib_s32 qq = opposite_quadrants[dir_bit][i];
       
  3203 
       
  3204       if (node->tag & (1 << qq)) {
       
  3205         /* Here is alone color cell. Check the distance */
       
  3206         mlib_s32 newindex = node->contents.index[qq];
       
  3207         mlib_u32 newpalc0, newpalc1, newpalc2, newpalc3;
       
  3208         mlib_u32 newdistance;
       
  3209 
       
  3210         newpalc0 = base[0][newindex];
       
  3211         newpalc1 = base[1][newindex];
       
  3212         newpalc2 = base[2][newindex];
       
  3213         newpalc3 = base[3][newindex];
       
  3214         newdistance = FIND_DISTANCE_4(c[0], newpalc0,
       
  3215                                       c[1], newpalc1, c[2], newpalc2, c[3], newpalc3, 0);
       
  3216 
       
  3217         if (distance > newdistance) {
       
  3218           *found_color = newindex;
       
  3219           distance = newdistance;
       
  3220         }
       
  3221       }
       
  3222       else if (node->contents.quadrants[qq])
       
  3223         distance =
       
  3224           mlib_search_quadrant_part_to_left_U8_4(node->contents.quadrants[qq],
       
  3225                                                  distance, found_color, c, base,
       
  3226                                                  position, pass - 1, dir_bit);
       
  3227     }
       
  3228   }
       
  3229   else {                                    /* Search whole quadrant */
       
  3230 
       
  3231     mlib_s32 mask = 1 << dir_bit;
       
  3232 
       
  3233     for (i = 0; i < 16; i++) {
       
  3234 
       
  3235       if (node->tag & (1 << i)) {
       
  3236         /* Here is alone color cell. Check the distance */
       
  3237         mlib_s32 newindex = node->contents.index[i];
       
  3238         mlib_u32 newpalc0, newpalc1, newpalc2, newpalc3;
       
  3239         mlib_u32 newdistance;
       
  3240 
       
  3241         newpalc0 = base[0][newindex];
       
  3242         newpalc1 = base[1][newindex];
       
  3243         newpalc2 = base[2][newindex];
       
  3244         newpalc3 = base[3][newindex];
       
  3245         newdistance = FIND_DISTANCE_4(c[0], newpalc0,
       
  3246                                       c[1], newpalc1, c[2], newpalc2, c[3], newpalc3, 0);
       
  3247 
       
  3248         if (distance > newdistance) {
       
  3249           *found_color = newindex;
       
  3250           distance = newdistance;
       
  3251         }
       
  3252       }
       
  3253       else if (node->contents.quadrants[i]) {
       
  3254 
       
  3255         if (i & mask)
       
  3256           /* This quadrant may require partial checking */
       
  3257           distance =
       
  3258             mlib_search_quadrant_part_to_left_U8_4(node->contents.quadrants[i],
       
  3259                                                    distance, found_color, c,
       
  3260                                                    base,
       
  3261                                                    position + current_size,
       
  3262                                                    pass - 1, dir_bit);
       
  3263         else
       
  3264           /* Here we should check all */
       
  3265           distance =
       
  3266             mlib_search_quadrant_U8_4(node->contents.quadrants[i], distance,
       
  3267                                       found_color, c[0], c[1], c[2], c[3], base);
       
  3268       }
       
  3269     }
       
  3270   }
       
  3271 
       
  3272   return distance;
       
  3273 }
       
  3274 
       
  3275 /***************************************************************/
       
  3276 mlib_u32 mlib_search_quadrant_part_to_right_U8_4(struct lut_node_4 *node,
       
  3277                                                  mlib_u32          distance,
       
  3278                                                   mlib_s32    *found_color,
       
  3279                                                  const mlib_u32    *c,
       
  3280                                                  const mlib_u8     **base,
       
  3281                                                  mlib_u32          position,
       
  3282                                                  mlib_s32          pass,
       
  3283                                                  mlib_s32          dir_bit)
       
  3284 {
       
  3285   mlib_u32 current_size = 1 << pass;
       
  3286   mlib_s32 i;
       
  3287   static mlib_s32 opposite_quadrants[4][8] = {
       
  3288     {1, 3, 5, 7, 9, 11, 13, 15},
       
  3289     {2, 3, 6, 7, 10, 11, 14, 15},
       
  3290     {4, 5, 6, 7, 12, 13, 14, 15},
       
  3291     {8, 9, 10, 11, 12, 13, 14, 15}
       
  3292   };
       
  3293 
       
  3294 /* Search only quadrant's half untill it is necessary to check the
       
  3295   whole quadrant */
       
  3296 
       
  3297   if (distance <= (c[dir_bit] - position - current_size) * (c[dir_bit] - position - current_size)) { /* Search half of quadrant */
       
  3298     for (i = 0; i < 8; i++) {
       
  3299       mlib_s32 qq = opposite_quadrants[dir_bit][i];
       
  3300 
       
  3301       if (node->tag & (1 << qq)) {
       
  3302         /* Here is alone color cell. Check the distance */
       
  3303         mlib_s32 newindex = node->contents.index[qq];
       
  3304         mlib_u32 newpalc0, newpalc1, newpalc2, newpalc3;
       
  3305         mlib_u32 newdistance;
       
  3306 
       
  3307         newpalc0 = base[0][newindex];
       
  3308         newpalc1 = base[1][newindex];
       
  3309         newpalc2 = base[2][newindex];
       
  3310         newpalc3 = base[3][newindex];
       
  3311         newdistance = FIND_DISTANCE_4(c[0], newpalc0,
       
  3312                                       c[1], newpalc1, c[2], newpalc2, c[3], newpalc3, 0);
       
  3313 
       
  3314         if (distance > newdistance) {
       
  3315           *found_color = newindex;
       
  3316           distance = newdistance;
       
  3317         }
       
  3318       }
       
  3319       else if (node->contents.quadrants[qq])
       
  3320         distance =
       
  3321           mlib_search_quadrant_part_to_right_U8_4(node->contents.quadrants[qq],
       
  3322                                                   distance, found_color, c,
       
  3323                                                   base, position + current_size,
       
  3324                                                   pass - 1, dir_bit);
       
  3325     }
       
  3326   }
       
  3327   else {                                    /* Search whole quadrant */
       
  3328 
       
  3329     mlib_s32 mask = 1 << dir_bit;
       
  3330 
       
  3331     for (i = 0; i < 16; i++) {
       
  3332 
       
  3333       if (node->tag & (1 << i)) {
       
  3334         /* Here is alone color cell. Check the distance */
       
  3335         mlib_s32 newindex = node->contents.index[i];
       
  3336         mlib_u32 newpalc0, newpalc1, newpalc2, newpalc3;
       
  3337         mlib_u32 newdistance;
       
  3338 
       
  3339         newpalc0 = base[0][newindex];
       
  3340         newpalc1 = base[1][newindex];
       
  3341         newpalc2 = base[2][newindex];
       
  3342         newpalc3 = base[3][newindex];
       
  3343         newdistance = FIND_DISTANCE_4(c[0], newpalc0,
       
  3344                                       c[1], newpalc1, c[2], newpalc2, c[3], newpalc3, 0);
       
  3345 
       
  3346         if (distance > newdistance) {
       
  3347           *found_color = newindex;
       
  3348           distance = newdistance;
       
  3349         }
       
  3350       }
       
  3351       else if (node->contents.quadrants[i]) {
       
  3352 
       
  3353         if (i & mask)
       
  3354           /* Here we should check all */
       
  3355           distance =
       
  3356             mlib_search_quadrant_U8_4(node->contents.quadrants[i], distance,
       
  3357                                       found_color, c[0], c[1], c[2], c[3], base);
       
  3358         else
       
  3359           /* This quadrant may require partial checking */
       
  3360           distance =
       
  3361             mlib_search_quadrant_part_to_right_U8_4(node->contents.quadrants[i],
       
  3362                                                     distance, found_color, c,
       
  3363                                                     base, position, pass - 1, dir_bit);
       
  3364       }
       
  3365     }
       
  3366   }
       
  3367 
       
  3368   return distance;
       
  3369 }
       
  3370 
       
  3371 /***************************************************************/
       
  3372 mlib_u32 mlib_search_quadrant_S16_4(struct lut_node_4 *node,
       
  3373                                     mlib_u32          distance,
       
  3374                                      mlib_s32    *found_color,
       
  3375                                     mlib_u32          c0,
       
  3376                                     mlib_u32          c1,
       
  3377                                     mlib_u32          c2,
       
  3378                                     mlib_u32          c3,
       
  3379                                     const mlib_s16    **base)
       
  3380 {
       
  3381   mlib_s32 i;
       
  3382 
       
  3383   for (i = 0; i < 16; i++) {
       
  3384 
       
  3385     if (node->tag & (1 << i)) {
       
  3386       /* Here is alone color cell. Check the distance */
       
  3387       mlib_s32 newindex = node->contents.index[i];
       
  3388       mlib_u32 newpalc0, newpalc1, newpalc2, newpalc3;
       
  3389       mlib_u32 newdistance;
       
  3390 
       
  3391       newpalc0 = base[0][newindex] - MLIB_S16_MIN;
       
  3392       newpalc1 = base[1][newindex] - MLIB_S16_MIN;
       
  3393       newpalc2 = base[2][newindex] - MLIB_S16_MIN;
       
  3394       newpalc3 = base[3][newindex] - MLIB_S16_MIN;
       
  3395       newdistance = FIND_DISTANCE_4(c0, newpalc0,
       
  3396                                     c1, newpalc1, c2, newpalc2, c3, newpalc3, 2);
       
  3397 
       
  3398       if (distance > newdistance) {
       
  3399         *found_color = newindex;
       
  3400         distance = newdistance;
       
  3401       }
       
  3402     }
       
  3403     else if (node->contents.quadrants[i])
       
  3404       distance =
       
  3405         mlib_search_quadrant_S16_4(node->contents.quadrants[i], distance,
       
  3406                                    found_color, c0, c1, c2, c3, base);
       
  3407   }
       
  3408 
       
  3409   return distance;
       
  3410 }
       
  3411 
       
  3412 /***************************************************************/
       
  3413 mlib_u32 mlib_search_quadrant_part_to_left_S16_4(struct lut_node_4 *node,
       
  3414                                                  mlib_u32          distance,
       
  3415                                                   mlib_s32    *found_color,
       
  3416                                                  const mlib_u32    *c,
       
  3417                                                  const mlib_s16    **base,
       
  3418                                                  mlib_u32          position,
       
  3419                                                  mlib_s32          pass,
       
  3420                                                  mlib_s32          dir_bit)
       
  3421 {
       
  3422   mlib_u32 current_size = 1 << pass;
       
  3423   mlib_s32 i;
       
  3424   static mlib_s32 opposite_quadrants[4][8] = {
       
  3425     {0, 2, 4, 6, 8, 10, 12, 14},
       
  3426     {0, 1, 4, 5, 8, 9, 12, 13},
       
  3427     {0, 1, 2, 3, 8, 9, 10, 11},
       
  3428     {0, 1, 2, 3, 4, 5, 6, 7}
       
  3429   };
       
  3430 
       
  3431 /* Search only quadrant's half untill it is necessary to check the
       
  3432   whole quadrant */
       
  3433 
       
  3434   if (distance < (((position + current_size - c[dir_bit]) * (position + current_size - c[dir_bit])) >> 2)) { /* Search half of quadrant */
       
  3435     for (i = 0; i < 8; i++) {
       
  3436       mlib_s32 qq = opposite_quadrants[dir_bit][i];
       
  3437 
       
  3438       if (node->tag & (1 << qq)) {
       
  3439         /* Here is alone color cell. Check the distance */
       
  3440         mlib_s32 newindex = node->contents.index[qq];
       
  3441         mlib_u32 newpalc0, newpalc1, newpalc2, newpalc3;
       
  3442         mlib_u32 newdistance;
       
  3443 
       
  3444         newpalc0 = base[0][newindex] - MLIB_S16_MIN;
       
  3445         newpalc1 = base[1][newindex] - MLIB_S16_MIN;
       
  3446         newpalc2 = base[2][newindex] - MLIB_S16_MIN;
       
  3447         newpalc3 = base[3][newindex] - MLIB_S16_MIN;
       
  3448         newdistance = FIND_DISTANCE_4(c[0], newpalc0,
       
  3449                                       c[1], newpalc1, c[2], newpalc2, c[3], newpalc3, 2);
       
  3450 
       
  3451         if (distance > newdistance) {
       
  3452           *found_color = newindex;
       
  3453           distance = newdistance;
       
  3454         }
       
  3455       }
       
  3456       else if (node->contents.quadrants[qq])
       
  3457         distance =
       
  3458           mlib_search_quadrant_part_to_left_S16_4(node->contents.quadrants[qq],
       
  3459                                                   distance, found_color, c,
       
  3460                                                   base, position, pass - 1, dir_bit);
       
  3461     }
       
  3462   }
       
  3463   else {                                    /* Search whole quadrant */
       
  3464 
       
  3465     mlib_s32 mask = 1 << dir_bit;
       
  3466 
       
  3467     for (i = 0; i < 16; i++) {
       
  3468 
       
  3469       if (node->tag & (1 << i)) {
       
  3470         /* Here is alone color cell. Check the distance */
       
  3471         mlib_s32 newindex = node->contents.index[i];
       
  3472         mlib_u32 newpalc0, newpalc1, newpalc2, newpalc3;
       
  3473         mlib_u32 newdistance;
       
  3474 
       
  3475         newpalc0 = base[0][newindex] - MLIB_S16_MIN;
       
  3476         newpalc1 = base[1][newindex] - MLIB_S16_MIN;
       
  3477         newpalc2 = base[2][newindex] - MLIB_S16_MIN;
       
  3478         newpalc3 = base[3][newindex] - MLIB_S16_MIN;
       
  3479         newdistance = FIND_DISTANCE_4(c[0], newpalc0,
       
  3480                                       c[1], newpalc1, c[2], newpalc2, c[3], newpalc3, 2);
       
  3481 
       
  3482         if (distance > newdistance) {
       
  3483           *found_color = newindex;
       
  3484           distance = newdistance;
       
  3485         }
       
  3486       }
       
  3487       else if (node->contents.quadrants[i]) {
       
  3488 
       
  3489         if (i & mask)
       
  3490           /* This quadrant may require partial checking */
       
  3491           distance =
       
  3492             mlib_search_quadrant_part_to_left_S16_4(node->contents.quadrants[i],
       
  3493                                                     distance, found_color, c,
       
  3494                                                     base,
       
  3495                                                     position + current_size,
       
  3496                                                     pass - 1, dir_bit);
       
  3497         else
       
  3498           /* Here we should check all */
       
  3499           distance =
       
  3500             mlib_search_quadrant_S16_4(node->contents.quadrants[i], distance,
       
  3501                                        found_color, c[0], c[1], c[2], c[3], base);
       
  3502       }
       
  3503     }
       
  3504   }
       
  3505 
       
  3506   return distance;
       
  3507 }
       
  3508 
       
  3509 /***************************************************************/
       
  3510 mlib_u32 mlib_search_quadrant_part_to_right_S16_4(struct lut_node_4 *node,
       
  3511                                                   mlib_u32          distance,
       
  3512                                                    mlib_s32    *found_color,
       
  3513                                                   const mlib_u32    *c,
       
  3514                                                   const mlib_s16    **base,
       
  3515                                                   mlib_u32          position,
       
  3516                                                   mlib_s32          pass,
       
  3517                                                   mlib_s32          dir_bit)
       
  3518 {
       
  3519   mlib_u32 current_size = 1 << pass;
       
  3520   mlib_s32 i;
       
  3521   static mlib_s32 opposite_quadrants[4][8] = {
       
  3522     {1, 3, 5, 7, 9, 11, 13, 15},
       
  3523     {2, 3, 6, 7, 10, 11, 14, 15},
       
  3524     {4, 5, 6, 7, 12, 13, 14, 15},
       
  3525     {8, 9, 10, 11, 12, 13, 14, 15}
       
  3526   };
       
  3527 
       
  3528 /* Search only quadrant's half untill it is necessary to check the
       
  3529   whole quadrant */
       
  3530 
       
  3531   if (distance <= (((c[dir_bit] - position - current_size) * (c[dir_bit] - position - current_size)) >> 2)) { /* Search half of quadrant */
       
  3532     for (i = 0; i < 8; i++) {
       
  3533       mlib_s32 qq = opposite_quadrants[dir_bit][i];
       
  3534 
       
  3535       if (node->tag & (1 << qq)) {
       
  3536         /* Here is alone color cell. Check the distance */
       
  3537         mlib_s32 newindex = node->contents.index[qq];
       
  3538         mlib_u32 newpalc0, newpalc1, newpalc2, newpalc3;
       
  3539         mlib_u32 newdistance;
       
  3540 
       
  3541         newpalc0 = base[0][newindex] - MLIB_S16_MIN;
       
  3542         newpalc1 = base[1][newindex] - MLIB_S16_MIN;
       
  3543         newpalc2 = base[2][newindex] - MLIB_S16_MIN;
       
  3544         newpalc3 = base[3][newindex] - MLIB_S16_MIN;
       
  3545         newdistance = FIND_DISTANCE_4(c[0], newpalc0,
       
  3546                                       c[1], newpalc1, c[2], newpalc2, c[3], newpalc3, 2);
       
  3547 
       
  3548         if (distance > newdistance) {
       
  3549           *found_color = newindex;
       
  3550           distance = newdistance;
       
  3551         }
       
  3552       }
       
  3553       else if (node->contents.quadrants[qq])
       
  3554         distance =
       
  3555           mlib_search_quadrant_part_to_right_S16_4(node->contents.quadrants[qq],
       
  3556                                                    distance, found_color, c,
       
  3557                                                    base,
       
  3558                                                    position + current_size,
       
  3559                                                    pass - 1, dir_bit);
       
  3560     }
       
  3561   }
       
  3562   else {                                    /* Search whole quadrant */
       
  3563 
       
  3564     mlib_s32 mask = 1 << dir_bit;
       
  3565 
       
  3566     for (i = 0; i < 16; i++) {
       
  3567 
       
  3568       if (node->tag & (1 << i)) {
       
  3569         /* Here is alone color cell. Check the distance */
       
  3570         mlib_s32 newindex = node->contents.index[i];
       
  3571         mlib_u32 newpalc0, newpalc1, newpalc2, newpalc3;
       
  3572         mlib_u32 newdistance;
       
  3573 
       
  3574         newpalc0 = base[0][newindex] - MLIB_S16_MIN;
       
  3575         newpalc1 = base[1][newindex] - MLIB_S16_MIN;
       
  3576         newpalc2 = base[2][newindex] - MLIB_S16_MIN;
       
  3577         newpalc3 = base[3][newindex] - MLIB_S16_MIN;
       
  3578         newdistance = FIND_DISTANCE_4(c[0], newpalc0,
       
  3579                                       c[1], newpalc1, c[2], newpalc2, c[3], newpalc3, 2);
       
  3580 
       
  3581         if (distance > newdistance) {
       
  3582           *found_color = newindex;
       
  3583           distance = newdistance;
       
  3584         }
       
  3585       }
       
  3586       else if (node->contents.quadrants[i]) {
       
  3587 
       
  3588         if (i & mask)
       
  3589           /* Here we should check all */
       
  3590           distance =
       
  3591             mlib_search_quadrant_S16_4(node->contents.quadrants[i], distance,
       
  3592                                        found_color, c[0], c[1], c[2], c[3], base);
       
  3593         else
       
  3594           /* This quadrant may require partial checking */
       
  3595           distance =
       
  3596             mlib_search_quadrant_part_to_right_S16_4(node->contents.
       
  3597                                                      quadrants[i], distance,
       
  3598                                                      found_color, c, base,
       
  3599                                                      position, pass - 1, dir_bit);
       
  3600       }
       
  3601     }
       
  3602   }
       
  3603 
       
  3604   return distance;
       
  3605 }
       
  3606 
       
  3607 /***************************************************************/
       
  3608 
       
  3609 #define TAB_SIZE_mlib_u8   256
       
  3610 #define TAB_SIZE_mlib_s16 1024
       
  3611 
       
  3612 #define SRC_mlib_u8(i)    src[i]
       
  3613 #define SRC_mlib_s16(i)   (((mlib_u16*)src)[i] >> 6)
       
  3614 
       
  3615 /***************************************************************/
       
  3616 
       
  3617 #define DIMENSIONS_SEARCH_3(STYPE, DTYPE, STEP)                 \
       
  3618 {                                                               \
       
  3619   DTYPE  *tab0 = ((mlib_colormap *)state)->table;               \
       
  3620   DTYPE  *tab1 = tab0 + TAB_SIZE_##STYPE;                       \
       
  3621   DTYPE  *tab2 = tab1 + TAB_SIZE_##STYPE;                       \
       
  3622   mlib_s32 i;                                                   \
       
  3623                                                                 \
       
  3624   for (i = 0; i < length; i++) {                                \
       
  3625     dst[i] = tab0[SRC_##STYPE(0)] + tab1[SRC_##STYPE(1)] +      \
       
  3626              tab2[SRC_##STYPE(2)];                              \
       
  3627     src += STEP;                                                \
       
  3628   }                                                             \
       
  3629 }
       
  3630 
       
  3631 /***************************************************************/
       
  3632 
       
  3633 #define DIMENSIONS_SEARCH_4(STYPE, DTYPE)                       \
       
  3634 {                                                               \
       
  3635   DTYPE  *tab0 = ((mlib_colormap *)state)->table;               \
       
  3636   DTYPE  *tab1 = tab0 + TAB_SIZE_##STYPE;                       \
       
  3637   DTYPE  *tab2 = tab1 + TAB_SIZE_##STYPE;                       \
       
  3638   DTYPE  *tab3 = tab2 + TAB_SIZE_##STYPE;                       \
       
  3639   mlib_s32 i;                                                   \
       
  3640                                                                 \
       
  3641   for (i = 0; i < length; i++) {                                \
       
  3642     dst[i] = tab0[SRC_##STYPE(0)] + tab1[SRC_##STYPE(1)] +      \
       
  3643              tab2[SRC_##STYPE(2)] + tab3[SRC_##STYPE(3)];       \
       
  3644     src += 4;                                                   \
       
  3645   }                                                             \
       
  3646 }
       
  3647 
       
  3648 /***************************************************************/
       
  3649 void mlib_ImageColorTrue2IndexLine_U8_U8_3(const mlib_u8 *src,
       
  3650                                            mlib_u8       *dst,
       
  3651                                            mlib_s32      length,
       
  3652                                            const void    *state)
       
  3653 {
       
  3654   mlib_colormap *s = (mlib_colormap *)state;
       
  3655 
       
  3656   switch (s->method) {
       
  3657 #if LUT_BYTE_COLORS_3CHANNELS <= 256
       
  3658     case LUT_BINARY_TREE_SEARCH:
       
  3659       {
       
  3660         mlib_s32 bits = s->bits;
       
  3661         BINARY_TREE_SEARCH_3(U8, mlib_u8, 8, (MLIB_U8_MAX + 1), 0, 0, 3, 0);
       
  3662       }
       
  3663       break;
       
  3664 
       
  3665 #endif /* LUT_BYTE_COLORS_3CHANNELS <= 256 */
       
  3666     case LUT_COLOR_CUBE_SEARCH:
       
  3667       {
       
  3668         COLOR_CUBE_U8_3_SEARCH(mlib_u8, 0, 3);
       
  3669       }
       
  3670       break;
       
  3671 
       
  3672     case LUT_STUPID_SEARCH:
       
  3673       {
       
  3674 #ifdef USE_VIS_CODE
       
  3675         FIND_NEAREST_U8_3;
       
  3676 #else
       
  3677         FIND_NEAREST_U8_3_C(0, 3);
       
  3678 #endif
       
  3679       }
       
  3680       break;
       
  3681 
       
  3682     case LUT_COLOR_DIMENSIONS:
       
  3683       DIMENSIONS_SEARCH_3(mlib_u8, mlib_u8, 3)
       
  3684       break;
       
  3685   }
       
  3686 }
       
  3687 
       
  3688 /***************************************************************/
       
  3689 void mlib_ImageColorTrue2IndexLine_U8_U8_3_in_4(const mlib_u8 *src,
       
  3690                                                 mlib_u8       *dst,
       
  3691                                                 mlib_s32      length,
       
  3692                                                 const void    *state)
       
  3693 {
       
  3694   mlib_colormap *s = (mlib_colormap *)state;
       
  3695 
       
  3696   switch (s->method) {
       
  3697 #if LUT_BYTE_COLORS_3CHANNELS <= 256
       
  3698     case LUT_BINARY_TREE_SEARCH:
       
  3699       {
       
  3700         mlib_s32 bits = s->bits;
       
  3701         BINARY_TREE_SEARCH_3(U8, mlib_u8, 8, (MLIB_U8_MAX + 1), 0, 1, 4, 0);
       
  3702         break;
       
  3703       }
       
  3704 
       
  3705 #endif /* LUT_BYTE_COLORS_3CHANNELS <= 256 */
       
  3706     case LUT_COLOR_CUBE_SEARCH:
       
  3707       {
       
  3708         COLOR_CUBE_U8_3_SEARCH(mlib_u8, 1, 4);
       
  3709         break;
       
  3710       }
       
  3711 
       
  3712     case LUT_STUPID_SEARCH:
       
  3713       {
       
  3714 #ifdef USE_VIS_CODE
       
  3715         FIND_NEAREST_U8_3_IN4;
       
  3716 #else
       
  3717         FIND_NEAREST_U8_3_C(1, 4);
       
  3718 #endif
       
  3719         break;
       
  3720       }
       
  3721 
       
  3722     case LUT_COLOR_DIMENSIONS:
       
  3723       src++;
       
  3724       DIMENSIONS_SEARCH_3(mlib_u8, mlib_u8, 4)
       
  3725       break;
       
  3726   }
       
  3727 }
       
  3728 
       
  3729 /***************************************************************/
       
  3730 void mlib_ImageColorTrue2IndexLine_U8_U8_4(const mlib_u8 *src,
       
  3731                                            mlib_u8       *dst,
       
  3732                                            mlib_s32      length,
       
  3733                                            const void    *state)
       
  3734 {
       
  3735   mlib_colormap *s = (mlib_colormap *)state;
       
  3736 
       
  3737   switch (s->method) {
       
  3738 #if LUT_BYTE_COLORS_4CHANNELS <= 256
       
  3739     case LUT_BINARY_TREE_SEARCH:
       
  3740       {
       
  3741         mlib_s32 bits = s->bits;
       
  3742         BINARY_TREE_SEARCH_4(U8, mlib_u8, 8, (MLIB_U8_MAX + 1), 0, 0);
       
  3743         break;
       
  3744       }
       
  3745 
       
  3746 #endif /* LUT_BYTE_COLORS_4CHANNELS <= 256 */
       
  3747     case LUT_COLOR_CUBE_SEARCH:
       
  3748       {
       
  3749         COLOR_CUBE_U8_4_SEARCH(mlib_u8);
       
  3750         break;
       
  3751       }
       
  3752 
       
  3753     case LUT_STUPID_SEARCH:
       
  3754       {
       
  3755 #ifdef USE_VIS_CODE
       
  3756         FIND_NEAREST_U8_4;
       
  3757 #else
       
  3758         FIND_NEAREST_U8_4_C;
       
  3759 #endif
       
  3760         break;
       
  3761       }
       
  3762 
       
  3763     case LUT_COLOR_DIMENSIONS:
       
  3764       DIMENSIONS_SEARCH_4(mlib_u8, mlib_u8)
       
  3765       break;
       
  3766   }
       
  3767 }
       
  3768 
       
  3769 /***************************************************************/
       
  3770 void mlib_ImageColorTrue2IndexLine_U8_S16_3(const mlib_u8 *src,
       
  3771                                             mlib_s16      *dst,
       
  3772                                             mlib_s32      length,
       
  3773                                             const void    *state)
       
  3774 {
       
  3775   mlib_colormap *s = (mlib_colormap *)state;
       
  3776   mlib_s32 bits = s->bits;
       
  3777 
       
  3778   switch (s->method) {
       
  3779     case LUT_BINARY_TREE_SEARCH:
       
  3780       {
       
  3781         BINARY_TREE_SEARCH_3(U8, mlib_u8, 8, (MLIB_U8_MAX + 1), 0, 0, 3, 0);
       
  3782         break;
       
  3783       }
       
  3784 
       
  3785     case LUT_COLOR_CUBE_SEARCH:
       
  3786       {
       
  3787         switch (s->indexsize) {
       
  3788           case 1:
       
  3789             {
       
  3790               COLOR_CUBE_U8_3_SEARCH(mlib_u8, 0, 3);
       
  3791               break;
       
  3792             }
       
  3793 
       
  3794           case 2:
       
  3795             {
       
  3796               COLOR_CUBE_U8_3_SEARCH(mlib_s16, 0, 3);
       
  3797               break;
       
  3798             }
       
  3799         }
       
  3800 
       
  3801         break;
       
  3802       }
       
  3803 
       
  3804     case LUT_STUPID_SEARCH:
       
  3805       {
       
  3806 #ifdef USE_VIS_CODE
       
  3807         FIND_NEAREST_U8_3;
       
  3808 #else
       
  3809         FIND_NEAREST_U8_3_C(0, 3);
       
  3810 #endif
       
  3811         break;
       
  3812       }
       
  3813 
       
  3814     case LUT_COLOR_DIMENSIONS:
       
  3815       DIMENSIONS_SEARCH_3(mlib_u8, mlib_s16, 3)
       
  3816       break;
       
  3817   }
       
  3818 }
       
  3819 
       
  3820 /***************************************************************/
       
  3821 void mlib_ImageColorTrue2IndexLine_U8_S16_3_in_4(const mlib_u8 *src,
       
  3822                                                  mlib_s16      *dst,
       
  3823                                                  mlib_s32      length,
       
  3824                                                  const void    *state)
       
  3825 {
       
  3826   mlib_colormap *s = (mlib_colormap *)state;
       
  3827   mlib_s32 bits = s->bits;
       
  3828 
       
  3829   switch (s->method) {
       
  3830     case LUT_BINARY_TREE_SEARCH:
       
  3831       {
       
  3832         BINARY_TREE_SEARCH_3(U8, mlib_u8, 8, (MLIB_U8_MAX + 1), 0, 1, 4, 0);
       
  3833         break;
       
  3834       }
       
  3835 
       
  3836     case LUT_COLOR_CUBE_SEARCH:
       
  3837       {
       
  3838         switch (s->indexsize) {
       
  3839           case 1:
       
  3840             {
       
  3841               COLOR_CUBE_U8_3_SEARCH(mlib_u8, 1, 4);
       
  3842               break;
       
  3843             }
       
  3844 
       
  3845           case 2:
       
  3846             {
       
  3847               COLOR_CUBE_U8_3_SEARCH(mlib_s16, 1, 4);
       
  3848               break;
       
  3849             }
       
  3850         }
       
  3851 
       
  3852         break;
       
  3853       }
       
  3854 
       
  3855     case LUT_STUPID_SEARCH:
       
  3856       {
       
  3857 #ifdef USE_VIS_CODE
       
  3858         FIND_NEAREST_U8_3_IN4;
       
  3859 #else
       
  3860         FIND_NEAREST_U8_3_C(1, 4);
       
  3861 #endif
       
  3862         break;
       
  3863       }
       
  3864 
       
  3865     case LUT_COLOR_DIMENSIONS:
       
  3866       src++;
       
  3867       DIMENSIONS_SEARCH_3(mlib_u8, mlib_s16, 4)
       
  3868       break;
       
  3869   }
       
  3870 }
       
  3871 
       
  3872 /***************************************************************/
       
  3873 void mlib_ImageColorTrue2IndexLine_U8_S16_4(const mlib_u8 *src,
       
  3874                                             mlib_s16      *dst,
       
  3875                                             mlib_s32      length,
       
  3876                                             const void    *state)
       
  3877 {
       
  3878   mlib_colormap *s = (mlib_colormap *)state;
       
  3879   mlib_s32 bits = s->bits;
       
  3880 
       
  3881   switch (s->method) {
       
  3882     case LUT_BINARY_TREE_SEARCH:
       
  3883       {
       
  3884         BINARY_TREE_SEARCH_4(U8, mlib_u8, 8, (MLIB_U8_MAX + 1), 0, 0);
       
  3885         break;
       
  3886       }
       
  3887 
       
  3888     case LUT_COLOR_CUBE_SEARCH:
       
  3889       {
       
  3890         switch (s->indexsize) {
       
  3891           case 1:
       
  3892             {
       
  3893               COLOR_CUBE_U8_4_SEARCH(mlib_u8);
       
  3894               break;
       
  3895             }
       
  3896 
       
  3897           case 2:
       
  3898             {
       
  3899               COLOR_CUBE_U8_4_SEARCH(mlib_s16);
       
  3900               break;
       
  3901             }
       
  3902         }
       
  3903 
       
  3904         break;
       
  3905       }
       
  3906 
       
  3907     case LUT_STUPID_SEARCH:
       
  3908       {
       
  3909 #ifdef USE_VIS_CODE
       
  3910         FIND_NEAREST_U8_4;
       
  3911 #else
       
  3912         FIND_NEAREST_U8_4_C;
       
  3913 #endif
       
  3914         break;
       
  3915       }
       
  3916 
       
  3917     case LUT_COLOR_DIMENSIONS:
       
  3918       DIMENSIONS_SEARCH_4(mlib_u8, mlib_s16)
       
  3919       break;
       
  3920   }
       
  3921 }
       
  3922 
       
  3923 /***************************************************************/
       
  3924 void mlib_ImageColorTrue2IndexLine_S16_S16_3(const mlib_s16 *src,
       
  3925                                              mlib_s16       *dst,
       
  3926                                              mlib_s32       length,
       
  3927                                              const void     *state)
       
  3928 {
       
  3929   mlib_colormap *s = (mlib_colormap *)state;
       
  3930   mlib_s32 bits = s->bits;
       
  3931 
       
  3932   switch (s->method) {
       
  3933     case LUT_BINARY_TREE_SEARCH:
       
  3934       {
       
  3935         BINARY_TREE_SEARCH_3(S16, mlib_s16, 16, ((MLIB_S16_MAX + 1) * 2),
       
  3936                              MLIB_S16_MIN, 0, 3, 2);
       
  3937         break;
       
  3938       }
       
  3939 
       
  3940     case LUT_COLOR_CUBE_SEARCH:
       
  3941       {
       
  3942         switch (s->indexsize) {
       
  3943           case 1:
       
  3944             {
       
  3945               COLOR_CUBE_S16_3_SEARCH(mlib_u8, 0, 3);
       
  3946               break;
       
  3947             }
       
  3948 
       
  3949           case 2:
       
  3950             {
       
  3951               COLOR_CUBE_S16_3_SEARCH(mlib_s16, 0, 3);
       
  3952               break;
       
  3953             }
       
  3954         }
       
  3955 
       
  3956         break;
       
  3957       }
       
  3958 
       
  3959     case LUT_STUPID_SEARCH:
       
  3960       {
       
  3961         FIND_NEAREST_S16_3(0, 3);
       
  3962         break;
       
  3963       }
       
  3964 
       
  3965     case LUT_COLOR_DIMENSIONS:
       
  3966       DIMENSIONS_SEARCH_3(mlib_s16, mlib_s16, 3)
       
  3967       break;
       
  3968   }
       
  3969 }
       
  3970 
       
  3971 /***************************************************************/
       
  3972 void mlib_ImageColorTrue2IndexLine_S16_S16_3_in_4(const mlib_s16 *src,
       
  3973                                                   mlib_s16       *dst,
       
  3974                                                   mlib_s32       length,
       
  3975                                                   const void     *state)
       
  3976 {
       
  3977   mlib_colormap *s = (mlib_colormap *)state;
       
  3978   mlib_s32 bits = s->bits;
       
  3979 
       
  3980   switch (s->method) {
       
  3981     case LUT_BINARY_TREE_SEARCH:
       
  3982       {
       
  3983         BINARY_TREE_SEARCH_3(S16, mlib_s16, 16, ((MLIB_S16_MAX + 1) * 2),
       
  3984                              MLIB_S16_MIN, 1, 4, 2);
       
  3985         break;
       
  3986       }
       
  3987 
       
  3988     case LUT_COLOR_CUBE_SEARCH:
       
  3989       {
       
  3990         switch (s->indexsize) {
       
  3991           case 1:
       
  3992             {
       
  3993               COLOR_CUBE_S16_3_SEARCH(mlib_u8, 1, 4);
       
  3994               break;
       
  3995             }
       
  3996 
       
  3997           case 2:
       
  3998             {
       
  3999               COLOR_CUBE_S16_3_SEARCH(mlib_s16, 1, 4);
       
  4000               break;
       
  4001             }
       
  4002         }
       
  4003 
       
  4004         break;
       
  4005       }
       
  4006 
       
  4007     case LUT_STUPID_SEARCH:
       
  4008       {
       
  4009         FIND_NEAREST_S16_3(1, 4);
       
  4010         break;
       
  4011       }
       
  4012 
       
  4013     case LUT_COLOR_DIMENSIONS:
       
  4014       src++;
       
  4015       DIMENSIONS_SEARCH_3(mlib_s16, mlib_s16, 4)
       
  4016       break;
       
  4017   }
       
  4018 }
       
  4019 
       
  4020 /***************************************************************/
       
  4021 void mlib_ImageColorTrue2IndexLine_S16_S16_4(const mlib_s16 *src,
       
  4022                                              mlib_s16       *dst,
       
  4023                                              mlib_s32       length,
       
  4024                                              const void     *state)
       
  4025 {
       
  4026   mlib_colormap *s = (mlib_colormap *)state;
       
  4027   mlib_s32 bits = s->bits;
       
  4028 
       
  4029   switch (s->method) {
       
  4030     case LUT_BINARY_TREE_SEARCH:
       
  4031       {
       
  4032         BINARY_TREE_SEARCH_4(S16, mlib_s16, 16, ((MLIB_S16_MAX + 1) * 2),
       
  4033                              MLIB_S16_MIN, 2);
       
  4034         break;
       
  4035       }
       
  4036 
       
  4037     case LUT_COLOR_CUBE_SEARCH:
       
  4038       {
       
  4039         switch (s->indexsize) {
       
  4040           case 1:
       
  4041             {
       
  4042               COLOR_CUBE_S16_4_SEARCH(mlib_u8);
       
  4043               break;
       
  4044             }
       
  4045 
       
  4046           case 2:
       
  4047             {
       
  4048               COLOR_CUBE_S16_4_SEARCH(mlib_s16);
       
  4049               break;
       
  4050             }
       
  4051         }
       
  4052 
       
  4053         break;
       
  4054       }
       
  4055 
       
  4056     case LUT_STUPID_SEARCH:
       
  4057       {
       
  4058         FIND_NEAREST_S16_4;
       
  4059         break;
       
  4060       }
       
  4061 
       
  4062     case LUT_COLOR_DIMENSIONS:
       
  4063       DIMENSIONS_SEARCH_4(mlib_s16, mlib_s16)
       
  4064       break;
       
  4065   }
       
  4066 }
       
  4067 
       
  4068 /***************************************************************/
       
  4069 void mlib_ImageColorTrue2IndexLine_S16_U8_3(const mlib_s16 *src,
       
  4070                                             mlib_u8        *dst,
       
  4071                                             mlib_s32       length,
       
  4072                                             const void     *state)
       
  4073 {
       
  4074   mlib_colormap *s = (mlib_colormap *)state;
       
  4075 
       
  4076   switch (s->method) {
       
  4077 #if LUT_SHORT_COLORS_3CHANNELS <= 256
       
  4078     case LUT_BINARY_TREE_SEARCH:
       
  4079       {
       
  4080         mlib_s32 bits = s->bits;
       
  4081         BINARY_TREE_SEARCH_3(S16, mlib_s16, 16, ((MLIB_S16_MAX + 1) * 2),
       
  4082                              MLIB_S16_MIN, 0, 3, 2);
       
  4083         break;
       
  4084       }
       
  4085 
       
  4086 #endif /* LUT_SHORT_COLORS_3CHANNELS <= 256 */
       
  4087     case LUT_COLOR_CUBE_SEARCH:
       
  4088       {
       
  4089         COLOR_CUBE_S16_3_SEARCH(mlib_u8, 0, 3);
       
  4090         break;
       
  4091       }
       
  4092 
       
  4093     case LUT_STUPID_SEARCH:
       
  4094       {
       
  4095         FIND_NEAREST_S16_3(0, 3);
       
  4096         break;
       
  4097       }
       
  4098 
       
  4099     case LUT_COLOR_DIMENSIONS:
       
  4100       DIMENSIONS_SEARCH_3(mlib_s16, mlib_u8, 3)
       
  4101       break;
       
  4102   }
       
  4103 }
       
  4104 
       
  4105 /***************************************************************/
       
  4106 void mlib_ImageColorTrue2IndexLine_S16_U8_3_in_4(const mlib_s16 *src,
       
  4107                                                  mlib_u8        *dst,
       
  4108                                                  mlib_s32       length,
       
  4109                                                  const void     *state)
       
  4110 {
       
  4111   mlib_colormap *s = (mlib_colormap *)state;
       
  4112 
       
  4113   switch (s->method) {
       
  4114 #if LUT_SHORT_COLORS_3CHANNELS <= 256
       
  4115     case LUT_BINARY_TREE_SEARCH:
       
  4116       {
       
  4117         mlib_s32 bits = s->bits;
       
  4118         BINARY_TREE_SEARCH_3(S16, mlib_s16, 16, ((MLIB_S16_MAX + 1) * 2),
       
  4119                              MLIB_S16_MIN, 1, 4, 2);
       
  4120         break;
       
  4121       }
       
  4122 
       
  4123 #endif /* LUT_SHORT_COLORS_3CHANNELS <= 256 */
       
  4124     case LUT_COLOR_CUBE_SEARCH:
       
  4125       {
       
  4126         COLOR_CUBE_S16_3_SEARCH(mlib_u8, 1, 4);
       
  4127         break;
       
  4128       }
       
  4129 
       
  4130     case LUT_STUPID_SEARCH:
       
  4131       {
       
  4132         FIND_NEAREST_S16_3(1, 4);
       
  4133         break;
       
  4134       }
       
  4135 
       
  4136     case LUT_COLOR_DIMENSIONS:
       
  4137       src++;
       
  4138       DIMENSIONS_SEARCH_3(mlib_s16, mlib_u8, 4)
       
  4139       break;
       
  4140   }
       
  4141 }
       
  4142 
       
  4143 /***************************************************************/
       
  4144 void mlib_ImageColorTrue2IndexLine_S16_U8_4(const mlib_s16 *src,
       
  4145                                             mlib_u8        *dst,
       
  4146                                             mlib_s32       length,
       
  4147                                             const void     *state)
       
  4148 {
       
  4149   mlib_colormap *s = (mlib_colormap *)state;
       
  4150 
       
  4151   switch (s->method) {
       
  4152 #if LUT_SHORT_COLORS_4CHANNELS <= 256
       
  4153     case LUT_BINARY_TREE_SEARCH:
       
  4154       {
       
  4155         mlib_s32 bits = s->bits;
       
  4156         BINARY_TREE_SEARCH_4(S16, mlib_s16, 16, ((MLIB_S16_MAX + 1) * 2),
       
  4157                              MLIB_S16_MIN, 2);
       
  4158         break;
       
  4159       }
       
  4160 
       
  4161 #endif /* LUT_SHORT_COLORS_4CHANNELS <= 256 */
       
  4162     case LUT_COLOR_CUBE_SEARCH:
       
  4163       {
       
  4164         COLOR_CUBE_S16_4_SEARCH(mlib_u8);
       
  4165         break;
       
  4166       }
       
  4167 
       
  4168     case LUT_STUPID_SEARCH:
       
  4169       {
       
  4170         FIND_NEAREST_S16_4;
       
  4171         break;
       
  4172       }
       
  4173 
       
  4174     case LUT_COLOR_DIMENSIONS:
       
  4175       DIMENSIONS_SEARCH_4(mlib_s16, mlib_u8)
       
  4176       break;
       
  4177   }
       
  4178 }
       
  4179 
       
  4180 /***************************************************************/
       
  4181 
       
  4182 #ifndef VIS
       
  4183 
       
  4184 void mlib_c_ImageThresh1_U81_1B(void     *psrc,
       
  4185                                 void     *pdst,
       
  4186                                 mlib_s32 src_stride,
       
  4187                                 mlib_s32 dst_stride,
       
  4188                                 mlib_s32 width,
       
  4189                                 mlib_s32 height,
       
  4190                                 void     *thresh,
       
  4191                                 void     *ghigh,
       
  4192                                 void     *glow,
       
  4193                                 mlib_s32 dbit_off);
       
  4194 
       
  4195 /***************************************************************/
       
  4196 
       
  4197 void mlib_ImageColorTrue2IndexLine_U8_BIT_1(const mlib_u8 *src,
       
  4198                                             mlib_u8       *dst,
       
  4199                                             mlib_s32      bit_offset,
       
  4200                                             mlib_s32      length,
       
  4201                                             const void    *state)
       
  4202 {
       
  4203   mlib_u8  *lut = ((mlib_colormap *)state)->table;
       
  4204   mlib_s32 thresh[1];
       
  4205   mlib_s32 ghigh[1];
       
  4206   mlib_s32 glow[1];
       
  4207 
       
  4208   thresh[0] = lut[2];
       
  4209 
       
  4210   glow[0]  = lut[0] - lut[1];
       
  4211   ghigh[0] = lut[1] - lut[0];
       
  4212 
       
  4213   mlib_c_ImageThresh1_U81_1B((void*)src, dst, 0, 0, length, 1,
       
  4214                              thresh, ghigh, glow, bit_offset);
       
  4215 }
       
  4216 
       
  4217 #else
       
  4218 
       
  4219 /***************************************************************/
       
  4220 
       
  4221 void mlib_v_ImageThresh1B_U8_1(const mlib_u8  *src,
       
  4222                                mlib_s32       slb,
       
  4223                                mlib_u8        *dst,
       
  4224                                mlib_s32       dlb,
       
  4225                                mlib_s32       xsize,
       
  4226                                mlib_s32       ysize,
       
  4227                                mlib_s32       dbit_off,
       
  4228                                const mlib_s32 *th,
       
  4229                                mlib_s32       hc,
       
  4230                                mlib_s32       lc);
       
  4231 
       
  4232 /***************************************************************/
       
  4233 
       
  4234 void mlib_ImageColorTrue2IndexLine_U8_BIT_1(const mlib_u8 *src,
       
  4235                                             mlib_u8       *dst,
       
  4236                                             mlib_s32      bit_offset,
       
  4237                                             mlib_s32      length,
       
  4238                                             const void    *state)
       
  4239 {
       
  4240   mlib_u8  *lut = ((mlib_colormap *)state)->table;
       
  4241   mlib_s32 thresh[4];
       
  4242   mlib_s32 ghigh[1];
       
  4243   mlib_s32 glow[1];
       
  4244 
       
  4245   thresh[0] = thresh[1] = thresh[2] = thresh[3] = lut[2];
       
  4246 
       
  4247   glow[0]  = (lut[1] < lut[0]) ? 0xFF : 0;
       
  4248   ghigh[0] = (lut[1] < lut[0]) ? 0 : 0xFF;
       
  4249 
       
  4250   mlib_v_ImageThresh1B_U8_1((void*)src, 0, dst, 0, length, 1,
       
  4251                             bit_offset, thresh, ghigh[0], glow[0]);
       
  4252 }
       
  4253 
       
  4254 /***************************************************************/
       
  4255 
       
  4256 #endif