1 /*
   2  * Copyright (c) 1998, 2003, 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 /*
  28  * FUNCTIONS
  29  *      mlib_ImageChannelExtract  - Copy the selected channels of the source
  30  *                                  image into the destination image
  31  *
  32  * SYNOPSIS
  33  *      mlib_status mlib_ImageChannelExtract(mlib_image *dst,
  34  *                                           mlib_image *src,
  35  *                                           mlib_s32   cmask);
  36  * ARGUMENT
  37  *    dst     Pointer to destination image.
  38  *    src     Pointer to source image.
  39  *    cmask   Source channel selection mask.
  40  *    The least significant bit (LSB) is corresponding to the
  41  *    last channel in the source image data.
  42  *    The bits with value 1 stand for the channels selected.
  43  *    If more than N channels are selected, the leftmost N
  44  *    channels are extracted, where N is the number of channels
  45  *    in the destination image.
  46  *
  47  * RESTRICTION
  48  *    The src and dst must have the same width, height and data type.
  49  *    The src and dst can have 1, 2, 3 or 4 channels.
  50  *    The src and dst can be either MLIB_BYTE, MLIB_SHORT,  MLIB_INT,
  51  *    MLIB_FLOAT or  MLIB_DOUBLE.
  52  *
  53  * DESCRIPTION
  54  *    Copy the selected channels of the source image into the
  55  *    destination image
  56  */
  57 
  58 #include <stdlib.h>
  59 #include "mlib_image.h"
  60 #include "mlib_ImageCheck.h"
  61 
  62 /***************************************************************/
  63 /* functions defined in mlib_ImageChannelExtract_1.c */
  64 
  65 void
  66 mlib_v_ImageChannelExtract_U8(mlib_u8  *src,   mlib_s32 slb,
  67                               mlib_u8  *dst,   mlib_s32 dlb,
  68                               mlib_s32 channels, mlib_s32 channeld,
  69                               mlib_s32 width,   mlib_s32 height,
  70                               mlib_s32 cmask);
  71 void
  72 mlib_v_ImageChannelExtract_S16(mlib_u16 *src,    mlib_s32 slb,
  73                                mlib_u16 *dst,    mlib_s32 dlb,
  74                                mlib_s32 channels, mlib_s32 channeld,
  75                                mlib_s32 width,    mlib_s32 height,
  76                                mlib_s32 cmask);
  77 void
  78 mlib_v_ImageChannelExtract_S32(mlib_s32 *src,    mlib_s32 slb,
  79                                mlib_s32 *dst,    mlib_s32 dlb,
  80                                mlib_s32 channels, mlib_s32 channeld,
  81                                mlib_s32 width,    mlib_s32 height,
  82                                mlib_s32 cmask);
  83 void
  84 mlib_v_ImageChannelExtract_D64(mlib_d64 *src,    mlib_s32 slb,
  85                                mlib_d64 *dst,    mlib_s32 dlb,
  86                                mlib_s32 channels, mlib_s32 channeld,
  87                                mlib_s32 width,    mlib_s32 height,
  88                                mlib_s32 cmask);
  89 
  90 /***************************************************************/
  91 
  92 void mlib_v_ImageChannelExtract_U8_2_1(mlib_u8  *sl,  mlib_s32 slb,
  93                                        mlib_u8 *dl,  mlib_s32 dlb,
  94                                        mlib_s32 width,   mlib_s32 height);
  95 
  96 void mlib_v_ImageChannelExtract_U8_3_2(mlib_u8  *sl,  mlib_s32 slb,
  97                                        mlib_u8 *dl,  mlib_s32 dlb,
  98                                        mlib_s32 width,   mlib_s32 height,
  99                                        mlib_s32 count1);
 100 
 101 void mlib_v_ImageChannelExtract_U8_4_2(mlib_u8  *sl,  mlib_s32 slb,
 102                                        mlib_u8  *dl,  mlib_s32 dlb,
 103                                        mlib_s32 width,   mlib_s32 height,
 104                                        mlib_s32 count1);
 105 
 106 void mlib_v_ImageChannelExtract_32_2_1(mlib_f32 *sl,  mlib_s32 slb,
 107                                        mlib_f32 *dl,   mlib_s32 dlb,
 108                                        mlib_s32 width, mlib_s32 height);
 109 
 110 void mlib_v_ImageChannelExtract_32_3_1(mlib_f32 *sl,  mlib_s32 slb,
 111                                        mlib_f32 *dl,   mlib_s32 dlb,
 112                                        mlib_s32 width, mlib_s32 height);
 113 
 114 void mlib_v_ImageChannelExtract_32_3_2(mlib_f32 *sp, mlib_s32 slb,
 115                                        mlib_f32 *dp, mlib_s32 dlb,
 116                                        mlib_s32 width, mlib_s32 height,
 117                                        mlib_s32 deltac1);
 118 
 119 void mlib_v_ImageChannelExtract_32_4_1(mlib_f32 *sl,  mlib_s32 slb,
 120                                        mlib_f32 *dl,   mlib_s32 dlb,
 121                                        mlib_s32 width, mlib_s32 height);
 122 
 123 void mlib_v_ImageChannelExtract_32_4_2(mlib_f32 *sp, mlib_s32 slb,
 124                                        mlib_f32 *dp, mlib_s32 dlb,
 125                                        mlib_s32 width, mlib_s32 height,
 126                                        mlib_s32 deltac1);
 127 
 128 void mlib_v_ImageChannelExtract_32_4_3(mlib_f32 *sl,  mlib_s32 slb,
 129                                        mlib_f32 *dl,   mlib_s32 dlb,
 130                                        mlib_s32 width, mlib_s32 height,
 131                                        mlib_s32  mask_off);
 132 
 133 /***************************************************************/
 134 
 135 void
 136 mlib_v_ImageChannelExtract_U8_21_A8D1X8(mlib_u8  *src,
 137                                         mlib_u8  *dst,
 138                                         mlib_s32 dsize,
 139                                         mlib_s32 cmask);
 140 void
 141 mlib_v_ImageChannelExtract_U8_21_A8D2X8(mlib_u8  *src,  mlib_s32 slb,
 142                                         mlib_u8  *dst,  mlib_s32 dlb,
 143                                         mlib_s32 xsize, mlib_s32 ysize,
 144                                         mlib_s32 cmask);
 145 void
 146 mlib_v_ImageChannelExtract_U8_21_D1(mlib_u8  *src,
 147                                     mlib_u8  *dst,
 148                                     mlib_s32 dsize,
 149                                     mlib_s32 cmask);
 150 void
 151 mlib_v_ImageChannelExtract_U8_21(mlib_u8  *src,  mlib_s32 slb,
 152                                  mlib_u8  *dst,  mlib_s32 dlb,
 153                                  mlib_s32 xsize, mlib_s32 ysize,
 154                                  mlib_s32 cmask);
 155 void
 156 mlib_v_ImageChannelExtract_U8_31_A8D1X8(mlib_u8  *src,
 157                                         mlib_u8  *dst,
 158                                         mlib_s32 dsize,
 159                                         mlib_s32 cmask);
 160 void
 161 mlib_v_ImageChannelExtract_U8_31_A8D2X8(mlib_u8  *src,  mlib_s32 slb,
 162                                         mlib_u8  *dst,  mlib_s32 dlb,
 163                                         mlib_s32 xsize, mlib_s32 ysize,
 164                                         mlib_s32 cmask);
 165 void
 166 mlib_v_ImageChannelExtract_U8_31_D1(mlib_u8  *src,
 167                                     mlib_u8  *dst,
 168                                     mlib_s32 dsize,
 169                                     mlib_s32 cmask);
 170 void
 171 mlib_v_ImageChannelExtract_U8_31(mlib_u8  *src,  mlib_s32 slb,
 172                                  mlib_u8  *dst,  mlib_s32 dlb,
 173                                  mlib_s32 xsize, mlib_s32 ysize,
 174                                  mlib_s32 cmask);
 175 void
 176 mlib_v_ImageChannelExtract_U8_41_A8D1X8(mlib_u8  *src,
 177                                         mlib_u8  *dst,
 178                                         mlib_s32 dsize,
 179                                         mlib_s32 cmask);
 180 void
 181 mlib_v_ImageChannelExtract_U8_41_A8D2X8(mlib_u8  *src,  mlib_s32 slb,
 182                                         mlib_u8  *dst,  mlib_s32 dlb,
 183                                         mlib_s32 xsize, mlib_s32 ysize,
 184                                         mlib_s32 cmask);
 185 void
 186 mlib_v_ImageChannelExtract_U8_41_D1(mlib_u8  *src,
 187                                     mlib_u8  *dst,
 188                                     mlib_s32 dsize,
 189                                     mlib_s32 cmask);
 190 void
 191 mlib_v_ImageChannelExtract_U8_41(mlib_u8  *src,  mlib_s32 slb,
 192                                  mlib_u8  *dst,  mlib_s32 dlb,
 193                                  mlib_s32 xsize, mlib_s32 ysize,
 194                                  mlib_s32 cmask);
 195 void
 196 mlib_v_ImageChannelExtract_S16_11_A8D1X4(mlib_s16 *src, mlib_s16 *dst,
 197                                          mlib_s32 dsize);
 198 void
 199 mlib_v_ImageChannelExtract_S16_21_A8D1X4(mlib_s16 *src,
 200                                          mlib_s16 *dst,
 201                                          mlib_s32 dsize,
 202                                          mlib_s32 cmask);
 203 void
 204 mlib_v_ImageChannelExtract_S16_21_A8D2X4(mlib_s16 *src,  mlib_s32 slb,
 205                                          mlib_s16 *dst,  mlib_s32 dlb,
 206                                          mlib_s32 xsize, mlib_s32 ysize,
 207                                          mlib_s32 cmask);
 208 void
 209 mlib_v_ImageChannelExtract_S16_21_D1(mlib_s16 *src,
 210                                      mlib_s16 *dst,
 211                                      mlib_s32 dsize,
 212                                      mlib_s32 cmask);
 213 void
 214 mlib_v_ImageChannelExtract_S16_21(mlib_s16 *src,  mlib_s32 slb,
 215                                   mlib_s16 *dst,  mlib_s32 dlb,
 216                                   mlib_s32 xsize, mlib_s32 ysize,
 217                                   mlib_s32 cmask);
 218 void
 219 mlib_v_ImageChannelExtract_S16_31_A8D1X4(mlib_s16 *src,
 220                                          mlib_s16 *dst,
 221                                          mlib_s32 dsize,
 222                                          mlib_s32 cmask);
 223 void
 224 mlib_v_ImageChannelExtract_S16_31_A8D2X4(mlib_s16 *src,  mlib_s32 slb,
 225                                          mlib_s16 *dst,  mlib_s32 dlb,
 226                                          mlib_s32 xsize, mlib_s32 ysize,
 227                                          mlib_s32 cmask);
 228 void
 229 mlib_v_ImageChannelExtract_S16_31_D1(mlib_s16 *src,
 230                                      mlib_s16 *dst,
 231                                      mlib_s32 dsize,
 232                                      mlib_s32 cmask);
 233 void
 234 mlib_v_ImageChannelExtract_S16_31(mlib_s16 *src,  mlib_s32 slb,
 235                                   mlib_s16 *dst,  mlib_s32 dlb,
 236                                   mlib_s32 xsize, mlib_s32 ysize,
 237                                   mlib_s32 cmask);
 238 void
 239 mlib_v_ImageChannelExtract_S16_41_A8D1X4(mlib_s16 *src,
 240                                          mlib_s16 *dst,
 241                                          mlib_s32 dsize,
 242                                          mlib_s32 cmask);
 243 void
 244 mlib_v_ImageChannelExtract_S16_41_A8D2X4(mlib_s16 *src,  mlib_s32 slb,
 245                                          mlib_s16 *dst,  mlib_s32 dlb,
 246                                          mlib_s32 xsize, mlib_s32 ysize,
 247                                          mlib_s32 cmask);
 248 void
 249 mlib_v_ImageChannelExtract_S16_41_D1(mlib_s16 *src,
 250                                      mlib_s16 *dst,
 251                                      mlib_s32 dsize,
 252                                      mlib_s32 cmask);
 253 void
 254 mlib_v_ImageChannelExtract_S16_41(mlib_s16 *src,  mlib_s32 slb,
 255                                   mlib_s16 *dst,  mlib_s32 dlb,
 256                                   mlib_s32 xsize, mlib_s32 ysize,
 257                                   mlib_s32 cmask);
 258 
 259 /***************************************************************/
 260 /* functions defined in mlib_ImageChannelExtract_43.c */
 261 
 262 void
 263 mlib_v_ImageChannelExtract_U8_43R_A8D1X8(mlib_u8  *src,
 264                                          mlib_u8  *dst,
 265                                          mlib_s32 dsize);
 266 void
 267 mlib_v_ImageChannelExtract_U8_43R_A8D2X8(mlib_u8  *src,  mlib_s32 slb,
 268                                          mlib_u8  *dst,  mlib_s32 dlb,
 269                                          mlib_s32 xsize, mlib_s32 ysize);
 270 void
 271 mlib_v_ImageChannelExtract_U8_43R_D1(mlib_u8  *src,
 272                                      mlib_u8  *dst,
 273                                      mlib_s32 dsize);
 274 void
 275 mlib_v_ImageChannelExtract_U8_43R(mlib_u8  *src,  mlib_s32 slb,
 276                                   mlib_u8  *dst,  mlib_s32 dlb,
 277                                   mlib_s32 xsize, mlib_s32 ysize);
 278 void
 279 mlib_v_ImageChannelExtract_S16_43R_A8D1X4(mlib_s16 *src,
 280                                           mlib_s16 *dst,
 281                                           mlib_s32 dsize);
 282 void
 283 mlib_v_ImageChannelExtract_S16_43R_A8D2X4(mlib_s16 *src,  mlib_s32 slb,
 284                                           mlib_s16 *dst,  mlib_s32 dlb,
 285                                           mlib_s32 xsize, mlib_s32 ysize);
 286 void
 287 mlib_v_ImageChannelExtract_S16_43R_D1(mlib_s16 *src,
 288                                       mlib_s16 *dst,
 289                                       mlib_s32 dsize);
 290 void
 291 mlib_v_ImageChannelExtract_S16_43R(mlib_s16 *src,  mlib_s32 slb,
 292                                    mlib_s16 *dst,  mlib_s32 dlb,
 293                                    mlib_s32 xsize, mlib_s32 ysize);
 294 void
 295 mlib_v_ImageChannelExtract_U8_43L_A8D1X8(mlib_u8  *src,
 296                                          mlib_u8  *dst,
 297                                          mlib_s32 dsize);
 298 void
 299 mlib_v_ImageChannelExtract_U8_43L_A8D2X8(mlib_u8  *src,  mlib_s32 slb,
 300                                          mlib_u8  *dst,  mlib_s32 dlb,
 301                                          mlib_s32 xsize, mlib_s32 ysize);
 302 void
 303 mlib_v_ImageChannelExtract_U8_43L_D1(mlib_u8  *src,
 304                                      mlib_u8  *dst,
 305                                      mlib_s32 dsize);
 306 void
 307 mlib_v_ImageChannelExtract_U8_43L(mlib_u8  *src,  mlib_s32 slb,
 308                                   mlib_u8  *dst,  mlib_s32 dlb,
 309                                   mlib_s32 xsize, mlib_s32 ysize);
 310 void
 311 mlib_v_ImageChannelExtract_S16_43L_A8D1X4(mlib_s16 *src,
 312                                           mlib_s16 *dst,
 313                                           mlib_s32 dsize);
 314 void
 315 mlib_v_ImageChannelExtract_S16_43L_A8D2X4(mlib_s16 *src,  mlib_s32 slb,
 316                                           mlib_s16 *dst,  mlib_s32 dlb,
 317                                           mlib_s32 xsize, mlib_s32 ysize);
 318 void
 319 mlib_v_ImageChannelExtract_S16_43L_D1(mlib_s16 *src,
 320                                       mlib_s16 *dst,
 321                                       mlib_s32 dsize);
 322 void
 323 mlib_v_ImageChannelExtract_S16_43L(mlib_s16 *src,  mlib_s32 slb,
 324                                    mlib_s16 *dst,  mlib_s32 dlb,
 325                                    mlib_s32 xsize, mlib_s32 ysize);
 326 
 327 /***************************************************************/
 328 
 329 #ifdef MLIB_TEST
 330 mlib_status
 331 mlib_v_ImageChannelExtract(mlib_image *dst,
 332                            mlib_image *src,
 333                            mlib_s32   cmask)
 334 #else
 335 mlib_status
 336 mlib_ImageChannelExtract(mlib_image *dst,
 337                          mlib_image *src,
 338                          mlib_s32   cmask)
 339 #endif
 340 {
 341   const mlib_s32  X8 = 0x7;
 342   const mlib_s32  X4 = 0x3;
 343   const mlib_s32  X2 = 0x1;
 344   const mlib_s32  A8D1   = MLIB_IMAGE_ALIGNED8 | MLIB_IMAGE_ONEDVECTOR;
 345   const mlib_s32  A8D2X8 = MLIB_IMAGE_ALIGNED8 | MLIB_IMAGE_STRIDE8X | MLIB_IMAGE_WIDTH8X;
 346   const mlib_s32  A8D2X4 = MLIB_IMAGE_ALIGNED8 | MLIB_IMAGE_STRIDE8X | MLIB_IMAGE_WIDTH4X;
 347   const mlib_s32  A8D2X2 = MLIB_IMAGE_ALIGNED8 | MLIB_IMAGE_STRIDE8X | MLIB_IMAGE_WIDTH2X;
 348   void      *sp;            /* pointer for pixel in src */
 349   void      *dp;            /* pointer for pixel in dst */
 350   mlib_s32  ncmask = 0;     /* normalized channel mask */
 351   mlib_s32  channels;       /* number of channels for src */
 352   mlib_s32  channeld;       /* number of channels for dst */
 353   mlib_s32  width, height;  /* for src and dst */
 354   mlib_s32  strides;        /* strides in bytes for src */
 355   mlib_s32  strided;        /* strides in bytes for dst */
 356   mlib_s32  flags;
 357   mlib_s32  flagd;
 358   mlib_s32  dsize;
 359   int       delta0 = 0;     /* offset of first selected channel */
 360   int       count1 = 0;     /* number of channels in first group */
 361   int       i, bit1count = 0;
 362 
 363   MLIB_IMAGE_CHECK(src);
 364   MLIB_IMAGE_CHECK(dst);
 365   MLIB_IMAGE_TYPE_EQUAL(src, dst);
 366   MLIB_IMAGE_SIZE_EQUAL(src, dst);
 367 
 368   channels = mlib_ImageGetChannels(src);
 369   channeld = mlib_ImageGetChannels(dst);
 370   width    = mlib_ImageGetWidth(src);
 371   height   = mlib_ImageGetHeight(src);
 372   strides  = mlib_ImageGetStride(src);
 373   strided  = mlib_ImageGetStride(dst);
 374   sp       = mlib_ImageGetData(src);
 375   dp       = mlib_ImageGetData(dst);
 376   flags    = mlib_ImageGetFlags(src);
 377   flagd    = mlib_ImageGetFlags(dst);
 378   dsize    = width * height;
 379 
 380   /* normalize the cmask, and count the number of bit with value 1 */
 381   for (i = (channels - 1); i >= 0; i--) {
 382     if (((cmask & (1 << i)) != 0) && (bit1count < channeld)) {
 383       ncmask += (1 << i);
 384       bit1count++;
 385     }
 386   }
 387 
 388   /* do not support the cases in which the number of selected channels is
 389    * less than the nubmber of channels in the destination image */
 390   if (bit1count < channeld) {
 391     return MLIB_FAILURE;
 392   }
 393 
 394   if (channels == channeld) {
 395 #ifdef MLIB_TEST
 396     mlib_v_ImageCopy(dst, src);
 397 #else
 398     mlib_ImageCopy(dst, src);
 399 #endif
 400     return MLIB_SUCCESS;
 401   }
 402 
 403   switch (mlib_ImageGetType(src)) {
 404     case MLIB_BYTE:
 405       if (channeld == 1) {
 406         switch (channels) {
 407           case 2:
 408             if (((flags & A8D1) == 0) &&
 409                 ((flagd & A8D1) == 0) &&
 410                 ((dsize & X8)   == 0)) {
 411               mlib_v_ImageChannelExtract_U8_21_A8D1X8((mlib_u8 *)sp,
 412                                                       (mlib_u8 *)dp,
 413                                                       dsize,
 414                                                       ncmask);
 415             }
 416             else if (((flags & A8D2X8) == 0) &&
 417                      ((flagd & A8D2X8) == 0)) {
 418               mlib_v_ImageChannelExtract_U8_21_A8D2X8((mlib_u8 *)sp, strides,
 419                                                       (mlib_u8 *)dp, strided,
 420                                                       width, height,
 421                                                       ncmask);
 422             }
 423             else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
 424                      ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
 425               mlib_v_ImageChannelExtract_U8_21_D1((mlib_u8 *)sp,
 426                                                   (mlib_u8 *)dp,
 427                                                   dsize,
 428                                                   ncmask);
 429             }
 430             else {
 431               mlib_v_ImageChannelExtract_U8_21((mlib_u8 *)sp, strides,
 432                                                (mlib_u8 *)dp, strided,
 433                                                width, height,
 434                                                ncmask);
 435             }
 436             return MLIB_SUCCESS;
 437 
 438           case 3:
 439             if (((flags & A8D1) == 0) &&
 440                 ((flagd & A8D1) == 0) &&
 441                 ((dsize & X8)   == 0)) {
 442               mlib_v_ImageChannelExtract_U8_31_A8D1X8((mlib_u8 *)sp,
 443                                                       (mlib_u8 *)dp,
 444                                                       dsize,
 445                                                       ncmask);
 446             }
 447             else if (((flags & A8D2X8) == 0) &&
 448                      ((flagd & A8D2X8) == 0)) {
 449               mlib_v_ImageChannelExtract_U8_31_A8D2X8((mlib_u8 *)sp, strides,
 450                                                       (mlib_u8 *)dp, strided,
 451                                                       width, height,
 452                                                       ncmask);
 453             }
 454             else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
 455                      ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
 456               mlib_v_ImageChannelExtract_U8_31_D1((mlib_u8 *)sp,
 457                                                   (mlib_u8 *)dp,
 458                                                   dsize,
 459                                                   ncmask);
 460             }
 461             else {
 462               mlib_v_ImageChannelExtract_U8_31((mlib_u8 *)sp, strides,
 463                                                (mlib_u8 *)dp, strided,
 464                                                width, height,
 465                                                ncmask);
 466             }
 467             return MLIB_SUCCESS;
 468 
 469           case 4:
 470             if (((flags & A8D1) == 0) &&
 471                 ((flagd & A8D1) == 0) &&
 472                 ((dsize & X8)   == 0)) {
 473               mlib_v_ImageChannelExtract_U8_41_A8D1X8((mlib_u8 *)sp,
 474                                                       (mlib_u8 *)dp,
 475                                                       dsize,
 476                                                       ncmask);
 477             }
 478             else if (((flags & A8D2X8) == 0) &&
 479                      ((flagd & A8D2X8) == 0)) {
 480               mlib_v_ImageChannelExtract_U8_41_A8D2X8((mlib_u8 *)sp, strides,
 481                                                       (mlib_u8 *)dp, strided,
 482                                                       width, height,
 483                                                       ncmask);
 484             }
 485             else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
 486                      ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
 487               mlib_v_ImageChannelExtract_U8_41_D1((mlib_u8 *)sp,
 488                                                   (mlib_u8 *)dp,
 489                                                   dsize,
 490                                                   ncmask);
 491             }
 492             else {
 493               mlib_v_ImageChannelExtract_U8_41((mlib_u8 *)sp, strides,
 494                                                (mlib_u8 *)dp, strided,
 495                                                width, height,
 496                                                ncmask);
 497             }
 498             return MLIB_SUCCESS;
 499 
 500           default:
 501             return MLIB_FAILURE;
 502         }
 503       }
 504       else if ((channels == 4) && (channeld == 3) && (ncmask == 7)) {
 505         if (((flags & A8D1) == 0) &&
 506             ((flagd & A8D1) == 0) &&
 507             ((dsize & X8)   == 0)) {
 508           mlib_v_ImageChannelExtract_U8_43R_A8D1X8((mlib_u8 *)sp,
 509                                                    (mlib_u8 *)dp,
 510                                                    dsize);
 511         }
 512         else if (((flags & A8D2X8) == 0) &&
 513                  ((flagd & A8D2X8) == 0)) {
 514           mlib_v_ImageChannelExtract_U8_43R_A8D2X8((mlib_u8 *)sp, strides,
 515                                                    (mlib_u8 *)dp, strided,
 516                                                    width, height);
 517         }
 518         else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
 519                  ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
 520           mlib_v_ImageChannelExtract_U8_43R_D1((mlib_u8 *)sp,
 521                                                (mlib_u8 *)dp,
 522                                                dsize);
 523         }
 524         else {
 525           mlib_v_ImageChannelExtract_U8_43R((mlib_u8 *)sp, strides,
 526                                             (mlib_u8 *)dp, strided,
 527                                             width, height);
 528         }
 529         return MLIB_SUCCESS;
 530       }
 531       else if ((channels == 4) && (channeld == 3) && (ncmask == 14)) {
 532         if (((flags & A8D1) == 0) &&
 533             ((flagd & A8D1) == 0) &&
 534             ((dsize & X8)   == 0)) {
 535           mlib_v_ImageChannelExtract_U8_43L_A8D1X8((mlib_u8 *)sp,
 536                                                    (mlib_u8 *)dp,
 537                                                    dsize);
 538         }
 539         else if (((flags & A8D2X8) == 0) &&
 540                  ((flagd & A8D2X8) == 0)) {
 541           mlib_v_ImageChannelExtract_U8_43L_A8D2X8((mlib_u8 *)sp, strides,
 542                                                    (mlib_u8 *)dp, strided,
 543                                                    width, height);
 544         }
 545         else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
 546                  ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
 547           mlib_v_ImageChannelExtract_U8_43L_D1((mlib_u8 *)sp,
 548                                                (mlib_u8 *)dp,
 549                                                dsize);
 550         }
 551         else {
 552           mlib_v_ImageChannelExtract_U8_43L((mlib_u8 *)sp, strides,
 553                                             (mlib_u8 *)dp, strided,
 554                                             width, height);
 555         }
 556         return MLIB_SUCCESS;
 557       }
 558       break;
 559 
 560     case MLIB_SHORT:
 561       if (channeld == 1) {
 562         switch (channels) {
 563           case 2:
 564             if (((flags & A8D1) == 0) &&
 565                 ((flagd & A8D1) == 0) &&
 566                 ((dsize & X4)   == 0)) {
 567               mlib_v_ImageChannelExtract_S16_21_A8D1X4((mlib_s16 *)sp,
 568                                                        (mlib_s16 *)dp,
 569                                                        dsize,
 570                                                        ncmask);
 571             }
 572             else if (((flags & A8D2X4) == 0) &&
 573                      ((flagd & A8D2X4) == 0)) {
 574               mlib_v_ImageChannelExtract_S16_21_A8D2X4((mlib_s16 *)sp, strides,
 575                                                        (mlib_s16 *)dp, strided,
 576                                                        width, height,
 577                                                        ncmask);
 578             }
 579             else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
 580                      ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
 581               mlib_v_ImageChannelExtract_S16_21_D1((mlib_s16 *)sp,
 582                                                    (mlib_s16 *)dp,
 583                                                    dsize,
 584                                                    ncmask);
 585             }
 586             else {
 587               mlib_v_ImageChannelExtract_S16_21((mlib_s16 *)sp, strides,
 588                                                 (mlib_s16 *)dp, strided,
 589                                                 width, height,
 590                                                 ncmask);
 591             }
 592             return MLIB_SUCCESS;
 593 
 594           case 3:
 595             if (((flags & A8D1) == 0) &&
 596                 ((flagd & A8D1) == 0) &&
 597                 ((dsize & X4)   == 0)) {
 598               mlib_v_ImageChannelExtract_S16_31_A8D1X4((mlib_s16 *)sp,
 599                                                        (mlib_s16 *)dp,
 600                                                        dsize,
 601                                                        ncmask);
 602             }
 603             else if (((flags & A8D2X4) == 0) &&
 604                      ((flagd & A8D2X4) == 0)) {
 605               mlib_v_ImageChannelExtract_S16_31_A8D2X4((mlib_s16 *)sp, strides,
 606                                                        (mlib_s16 *)dp, strided,
 607                                                        width, height,
 608                                                        ncmask);
 609             }
 610             else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
 611                      ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
 612               mlib_v_ImageChannelExtract_S16_31_D1((mlib_s16 *)sp,
 613                                                    (mlib_s16 *)dp,
 614                                                    dsize,
 615                                                    ncmask);
 616             }
 617             else {
 618               mlib_v_ImageChannelExtract_S16_31((mlib_s16 *)sp, strides,
 619                                                 (mlib_s16 *)dp, strided,
 620                                                 width, height,
 621                                                 ncmask);
 622             }
 623             return MLIB_SUCCESS;
 624 
 625           case 4:
 626             if (((flags & A8D1) == 0) &&
 627                 ((flagd & A8D1) == 0) &&
 628                 ((dsize & X4)   == 0)) {
 629               mlib_v_ImageChannelExtract_S16_41_A8D1X4((mlib_s16 *)sp,
 630                                                        (mlib_s16 *)dp,
 631                                                        dsize,
 632                                                        ncmask);
 633             }
 634             else if (((flags & A8D2X4) == 0) &&
 635                      ((flagd & A8D2X4) == 0)) {
 636               mlib_v_ImageChannelExtract_S16_41_A8D2X4((mlib_s16 *)sp, strides,
 637                                                        (mlib_s16 *)dp, strided,
 638                                                        width, height,
 639                                                        ncmask);
 640             }
 641             else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
 642                      ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
 643               mlib_v_ImageChannelExtract_S16_41_D1((mlib_s16 *)sp,
 644                                                    (mlib_s16 *)dp,
 645                                                    dsize,
 646                                                    ncmask);
 647             }
 648             else {
 649               mlib_v_ImageChannelExtract_S16_41((mlib_s16 *)sp, strides,
 650                                                 (mlib_s16 *)dp, strided,
 651                                                 width, height,
 652                                                 ncmask);
 653             }
 654             return MLIB_SUCCESS;
 655           default:
 656             return MLIB_FAILURE;
 657         }
 658       }
 659       else if ((channels == 4) && (channeld == 3) && (ncmask == 7)) {
 660         if (((flags & A8D1) == 0) &&
 661             ((flagd & A8D1) == 0) &&
 662             ((dsize & X4)   == 0)) {
 663           mlib_v_ImageChannelExtract_S16_43R_A8D1X4((mlib_s16 *)sp,
 664                                                     (mlib_s16 *)dp,
 665                                                     dsize);
 666         }
 667         else if (((flags & A8D2X4) == 0) &&
 668                  ((flagd & A8D2X4) == 0)) {
 669           mlib_v_ImageChannelExtract_S16_43R_A8D2X4((mlib_s16 *)sp, strides,
 670                                                     (mlib_s16 *)dp, strided,
 671                                                     width, height);
 672         }
 673         else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
 674                  ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
 675           mlib_v_ImageChannelExtract_S16_43R_D1((mlib_s16 *)sp,
 676                                                 (mlib_s16 *)dp,
 677                                                 dsize);
 678         }
 679         else {
 680           mlib_v_ImageChannelExtract_S16_43R((mlib_s16 *)sp, strides,
 681                                              (mlib_s16 *)dp, strided,
 682                                              width, height);
 683         }
 684         return MLIB_SUCCESS;
 685       }
 686       else if ((channels == 4) && (channeld == 3) && (ncmask == 14)) {
 687         if (((flags & A8D1) == 0) &&
 688             ((flagd & A8D1) == 0) &&
 689             ((dsize & X4)   == 0)) {
 690           mlib_v_ImageChannelExtract_S16_43L_A8D1X4((mlib_s16 *)sp,
 691                                                     (mlib_s16 *)dp,
 692                                                     dsize);
 693         }
 694         else if (((flags & A8D2X4) == 0) &&
 695                  ((flagd & A8D2X4) == 0)) {
 696           mlib_v_ImageChannelExtract_S16_43L_A8D2X4((mlib_s16 *)sp, strides,
 697                                                     (mlib_s16 *)dp, strided,
 698                                                     width, height);
 699         }
 700         else if (((flags & MLIB_IMAGE_ONEDVECTOR) == 0) &&
 701                  ((flagd & MLIB_IMAGE_ONEDVECTOR) == 0)) {
 702           mlib_v_ImageChannelExtract_S16_43L_D1((mlib_s16 *)sp,
 703                                                 (mlib_s16 *)dp,
 704                                                 dsize);
 705         }
 706         else {
 707           mlib_v_ImageChannelExtract_S16_43L((mlib_s16 *)sp, strides,
 708                                              (mlib_s16 *)dp, strided,
 709                                              width, height);
 710         }
 711         return MLIB_SUCCESS;
 712       }
 713       break;
 714 
 715   }
 716 
 717 /***************************************************************/
 718   /* From C version */
 719 
 720   for (i = (channels - 1); i >= 0; i--) {
 721     if (!(ncmask & (1 << i))) delta0++;
 722     else break;
 723   }
 724   for (; i >= 0; i--) {
 725     if (ncmask & (1 << i)) count1++;
 726     else break;
 727   }
 728 
 729   switch (mlib_ImageGetType(src)) {
 730     case MLIB_BYTE:
 731       {
 732         mlib_u8 *sl = (mlib_u8 *)sp + delta0;
 733         mlib_u8 *dl = (mlib_u8 *)dp;
 734 
 735         switch (channels*10 + channeld) {
 736           case 32:
 737             mlib_v_ImageChannelExtract_U8_3_2(sl, strides, dl, strided, width, height, count1);
 738             return MLIB_SUCCESS;
 739 
 740           case 42:
 741             if (ncmask == 0xA || ncmask == 0x5) { /* mask 1010 or 0101 */
 742               mlib_v_ImageChannelExtract_U8_2_1(sl, strides, dl, strided, 2*width, height);
 743               return MLIB_SUCCESS;
 744             }
 745             mlib_v_ImageChannelExtract_U8_4_2(sl, strides, dl, strided, width, height, count1);
 746             return MLIB_SUCCESS;
 747 
 748           case 43:
 749             mlib_v_ImageChannelExtract_U8((mlib_u8 *)sp, strides,
 750                                           (mlib_u8 *)dp, strided,
 751                                           channels, channeld,
 752                                           width, height,
 753                                           ncmask);
 754             return MLIB_SUCCESS;
 755 
 756           default: return MLIB_FAILURE;
 757         }
 758       }
 759 
 760     case MLIB_SHORT:
 761       mlib_v_ImageChannelExtract_S16((mlib_u16 *)sp, strides,
 762                                      (mlib_u16 *)dp, strided,
 763                                      channels,  channeld,
 764                                      width, height,
 765                                      ncmask);
 766       break;
 767 
 768     case MLIB_INT:
 769     case MLIB_FLOAT:
 770       {
 771         mlib_f32 *sl = (mlib_f32 *)sp + delta0;
 772         mlib_f32 *dl = (mlib_f32 *)dp;
 773         strides /= 4;
 774         strided /= 4;
 775 
 776         switch (channels*10 + channeld) {
 777           case 21:
 778             mlib_v_ImageChannelExtract_32_2_1(sl, strides, dl, strided, width, height);
 779             return MLIB_SUCCESS;
 780 
 781           case 31:
 782             mlib_v_ImageChannelExtract_32_3_1(sl, strides, dl, strided, width, height);
 783             return MLIB_SUCCESS;
 784 
 785           case 32:
 786             mlib_v_ImageChannelExtract_32_3_2(sl, strides, dl, strided, width, height, count1);
 787             return MLIB_SUCCESS;
 788 
 789           case 41:
 790             mlib_v_ImageChannelExtract_32_4_1(sl, strides, dl, strided, width, height);
 791             return MLIB_SUCCESS;
 792 
 793           case 42:
 794             if (ncmask == 0xA || ncmask == 0x5) { /* mask 1010 or 0101 */
 795               mlib_v_ImageChannelExtract_32_2_1(sl, strides, dl, strided, 2*width, height);
 796             } else {
 797               mlib_v_ImageChannelExtract_32_4_2(sl, strides, dl, strided, width, height, count1);
 798             }
 799             return MLIB_SUCCESS;
 800 
 801           case 43:
 802             mlib_v_ImageChannelExtract_32_4_3(sl, strides, dl, strided, width, height, count1);
 803             return MLIB_SUCCESS;
 804 
 805           default:
 806             return MLIB_FAILURE;
 807         }
 808       }
 809     case MLIB_DOUBLE:
 810       mlib_v_ImageChannelExtract_D64((mlib_d64 *)sp, strides,
 811                                      (mlib_d64 *)dp, strided,
 812                                      channels,  channeld,
 813                                      width, height,
 814                                      ncmask);
 815       break;
 816 
 817     case MLIB_BIT:
 818     default:
 819       return MLIB_FAILURE;  /* MLIB_BIT is not supported here */
 820   }
 821 
 822   return MLIB_SUCCESS;
 823 }
 824 
 825 /***************************************************************/