mlib_status mlib_convMxN_Index3_8_8nw()

in src/jdk/src/solaris/native/sun/awt/medialib/mlib_v_ImageConvIndex3_8_8nw.c [822:1671]


mlib_status mlib_convMxN_Index3_8_8nw(mlib_image *dst,
                                      mlib_image *src,
                                      mlib_s32   m,
                                      mlib_s32   n,
                                      mlib_s32   dm,
                                      mlib_s32   dn,
                                      mlib_s32   *kern,
                                      mlib_s32   scale,
                                      void       *colormap)

#else

mlib_status mlib_convMxN_8nw_f(mlib_image *dst,
                               mlib_image *src,
                               mlib_s32   m,
                               mlib_s32   n,
                               mlib_s32   dm,
                               mlib_s32   dn,
                               mlib_s32   *kern,
                               mlib_s32   scale)

#endif
{
  mlib_d64 *buffs_local[3*(MAX_N + 1)], **buffs = buffs_local, **buff;
  mlib_d64 *buff0, *buff1, *buff2, *buff3, *buffn, *buffd, *buffe;
  mlib_d64 s00, s01, s10, s11, s20, s21, s30, s31, s0, s1, s2, s3;
  mlib_d64 d00, d01, d10, d11, d20, d21, d30, d31;
  mlib_d64 dd, d0, d1;
  mlib_s32 ik, jk, ik_last, jk_size, coff, off, doff;
  DEF_VARS;
  DEF_EXTRA_VARS;

  if (n > MAX_N) {
    buffs = mlib_malloc(3*(n + 1)*sizeof(mlib_d64*));
    if (buffs == NULL) return MLIB_FAILURE;
  }

  buff = buffs + 2*(n + 1);

  sl = adr_src;
#ifdef CONV_INDEX
  dl = adr_dst + dn*dll + dm;
#else
  dl = adr_dst + dn*dll + dm*NCHAN;
#endif

  ssize = NCHAN*wid;
  dsize = (ssize + 7)/8;
  esize = dsize + 4;
  pbuff = mlib_malloc((n + 4)*esize*sizeof(mlib_d64));
  if (pbuff == NULL) {
    if (buffs != buffs_local) mlib_free(buffs);
    return MLIB_FAILURE;
  }

  for (i = 0; i < (n + 1); i++) buffs[i] = pbuff + i*esize;
  for (i = 0; i < (n + 1); i++) buffs[(n + 1) + i] = buffs[i];
  buffd = buffs[n] + esize;
  buffe = buffd + 2*esize;

  wid -= (m - 1);
  hgt -= (n - 1);
  xsize = ssize - NCHAN*(m - 1);
  emask = (0xFF00 >> (xsize & 7)) & 0xFF;

  vis_write_gsr(gsr_scale + 7);

  for (l = 0; l < n; l++) {
    mlib_d64 *buffn = buffs[l];
    sp = sl + l*sll;

#ifndef CONV_INDEX
    if ((mlib_addr)sp & 7) mlib_ImageCopy_na((void*)sp, (void*)buffn, ssize);
#else
#pragma pipeloop(0)
    for (i = 0; i < dsize; i += 3) {
      LOAD_SRC();
    }
#endif /* CONV_INDEX */
  }

  /* init buffer */
#pragma pipeloop(0)
  for (i = 0; i < (xsize + 7)/8; i++) {
    buffd[2*i    ] = drnd;
    buffd[2*i + 1] = drnd;
  }

  for (j = 0; j < hgt; j++) {
    mlib_d64 **buffc = buffs + buff_ind;
    mlib_f32 *pk = karr, k0, k1, k2, k3;
    sp = sl + n*sll;

    for (l = 0; l < n; l++) {
      buff[l] = buffc[l];
    }
    buffn  = buffc[n];

#ifndef CONV_INDEX
    for (l = 0; l < n; l++) {
      if ((((mlib_addr)(sl + l*sll)) & 7) == 0) buff[l] = (mlib_d64*)(sl + l*sll);
    }
    if ((mlib_addr)sp & 7) mlib_ImageCopy_na((void*)sp, (void*)buffn, ssize);
#endif

#ifdef CONV_INDEX
    ik_last = 0;
#else
    ik_last = (m - 1);
#endif

    for (jk = 0; jk < n; jk += jk_size) {
      jk_size = n - jk;
#ifdef CONV_INDEX
      if (jk_size >= 5) jk_size = 3;
      if (jk_size == 4) jk_size = 2;
#else
      if (jk_size >= 6) jk_size = 4;
      if (jk_size == 5) jk_size = 3;
#endif
      coff = 0;

      if (jk_size == 2) {

        for (ik = 0; ik < m; ik++, coff += NCHAN) {
          if (!jk && ik == ik_last) continue;

          k0 = pk[ik];
          k1 = pk[ik + m];

          doff  = coff/8;
          buff0 = buff[jk    ] + doff;
          buff1 = buff[jk + 1] + doff;

          off = coff & 7;
          vis_write_gsr(gsr_scale + off);

          s01 = buff0[0];
          s11 = buff1[0];
#pragma pipeloop(0)
          for (i = 0; i < (xsize + 7)/8; i++) {
            s00 = s01;
            s10 = s11;
            s01 = buff0[i + 1];
            s11 = buff1[i + 1];
            s0  = vis_faligndata(s00, s01);
            s1  = vis_faligndata(s10, s11);

            d00 = vis_fmul8x16au(vis_read_hi(s0), k0);
            d01 = vis_fmul8x16au(vis_read_lo(s0), k0);
            d10 = vis_fmul8x16au(vis_read_hi(s1), k1);
            d11 = vis_fmul8x16au(vis_read_lo(s1), k1);

            d0 = buffd[2*i];
            d1 = buffd[2*i + 1];
            d0 = vis_fpadd16(d00, d0);
            d0 = vis_fpadd16(d10, d0);
            d1 = vis_fpadd16(d01, d1);
            d1 = vis_fpadd16(d11, d1);
            buffd[2*i] = d0;
            buffd[2*i + 1] = d1;
          }

        }

        pk += 2*m;

      } else if (jk_size == 3) {

        for (ik = 0; ik < m; ik++, coff += NCHAN) {
          if (!jk && ik == ik_last) continue;

          k0 = pk[ik];
          k1 = pk[ik + m];
          k2 = pk[ik + 2*m];

          doff  = coff/8;
          buff0 = buff[jk    ] + doff;
          buff1 = buff[jk + 1] + doff;
          buff2 = buff[jk + 2] + doff;

          off = coff & 7;
          vis_write_gsr(gsr_scale + off);

          if (off == 0) {
#pragma pipeloop(0)
            for (i = 0; i < (xsize + 7)/8; i++) {
              d0 = buffd[2*i];
              d1 = buffd[2*i + 1];

              s0 = buff0[i];
              s1 = buff1[i];
              s2 = buff2[i];

              d00 = vis_fmul8x16au(vis_read_hi(s0), k0);
              d01 = vis_fmul8x16au(vis_read_lo(s0), k0);
              d10 = vis_fmul8x16au(vis_read_hi(s1), k1);
              d11 = vis_fmul8x16au(vis_read_lo(s1), k1);
              d20 = vis_fmul8x16au(vis_read_hi(s2), k2);
              d21 = vis_fmul8x16au(vis_read_lo(s2), k2);

              d00 = vis_fpadd16(d00, d10);
              d0  = vis_fpadd16(d20, d0);
              d0  = vis_fpadd16(d00, d0);
              d01 = vis_fpadd16(d01, d11);
              d1  = vis_fpadd16(d21, d1);
              d1  = vis_fpadd16(d01, d1);
              buffd[2*i] = d0;
              buffd[2*i + 1] = d1;
            }

          } else if (off == 4) {
            s01 = buff0[0];
            s11 = buff1[0];
            s21 = buff2[0];
#pragma pipeloop(0)
            for (i = 0; i < (xsize + 7)/8; i++) {
              d0 = buffd[2*i];
              d1 = buffd[2*i + 1];

              s00 = s01;
              s10 = s11;
              s20 = s21;
              s01 = buff0[i + 1];
              s11 = buff1[i + 1];
              s21 = buff2[i + 1];

              d00 = vis_fmul8x16au(vis_read_lo(s00), k0);
              d01 = vis_fmul8x16au(vis_read_hi(s01), k0);
              d10 = vis_fmul8x16au(vis_read_lo(s10), k1);
              d11 = vis_fmul8x16au(vis_read_hi(s11), k1);
              d20 = vis_fmul8x16au(vis_read_lo(s20), k2);
              d21 = vis_fmul8x16au(vis_read_hi(s21), k2);

              d00 = vis_fpadd16(d00, d10);
              d0  = vis_fpadd16(d20, d0);
              d0  = vis_fpadd16(d00, d0);
              d01 = vis_fpadd16(d01, d11);
              d1  = vis_fpadd16(d21, d1);
              d1  = vis_fpadd16(d01, d1);
              buffd[2*i] = d0;
              buffd[2*i + 1] = d1;
            }

          } else {
            s01 = buff0[0];
            s11 = buff1[0];
            s21 = buff2[0];
#pragma pipeloop(0)
            for (i = 0; i < (xsize + 7)/8; i++) {
              d0 = buffd[2*i];
              d1 = buffd[2*i + 1];

              s00 = s01;
              s10 = s11;
              s20 = s21;
              s01 = buff0[i + 1];
              s11 = buff1[i + 1];
              s21 = buff2[i + 1];
              s0  = vis_faligndata(s00, s01);
              s1  = vis_faligndata(s10, s11);
              s2  = vis_faligndata(s20, s21);

              d00 = vis_fmul8x16au(vis_read_hi(s0), k0);
              d01 = vis_fmul8x16au(vis_read_lo(s0), k0);
              d10 = vis_fmul8x16au(vis_read_hi(s1), k1);
              d11 = vis_fmul8x16au(vis_read_lo(s1), k1);
              d20 = vis_fmul8x16au(vis_read_hi(s2), k2);
              d21 = vis_fmul8x16au(vis_read_lo(s2), k2);

              d00 = vis_fpadd16(d00, d10);
              d0  = vis_fpadd16(d20, d0);
              d0  = vis_fpadd16(d00, d0);
              d01 = vis_fpadd16(d01, d11);
              d1  = vis_fpadd16(d21, d1);
              d1  = vis_fpadd16(d01, d1);
              buffd[2*i] = d0;
              buffd[2*i + 1] = d1;
            }
          }
        }

        pk += 3*m;

      } else { /* jk_size == 4 */

        for (ik = 0; ik < m; ik++, coff += NCHAN) {
          if (!jk && ik == ik_last) continue;

          k0 = pk[ik];
          k1 = pk[ik + m];
          k2 = pk[ik + 2*m];
          k3 = pk[ik + 3*m];

          doff  = coff/8;
          buff0 = buff[jk    ] + doff;
          buff1 = buff[jk + 1] + doff;
          buff2 = buff[jk + 2] + doff;
          buff3 = buff[jk + 3] + doff;

          off = coff & 7;
          vis_write_gsr(gsr_scale + off);

          if (off == 0) {

#pragma pipeloop(0)
            for (i = 0; i < (xsize + 7)/8; i++) {
              d0 = buffd[2*i];
              d1 = buffd[2*i + 1];

              s0 = buff0[i];
              s1 = buff1[i];
              s2 = buff2[i];
              s3 = buff3[i];

              d00 = vis_fmul8x16au(vis_read_hi(s0), k0);
              d01 = vis_fmul8x16au(vis_read_lo(s0), k0);
              d10 = vis_fmul8x16au(vis_read_hi(s1), k1);
              d11 = vis_fmul8x16au(vis_read_lo(s1), k1);
              d20 = vis_fmul8x16au(vis_read_hi(s2), k2);
              d21 = vis_fmul8x16au(vis_read_lo(s2), k2);
              d30 = vis_fmul8x16au(vis_read_hi(s3), k3);
              d31 = vis_fmul8x16au(vis_read_lo(s3), k3);

              d00 = vis_fpadd16(d00, d10);
              d20 = vis_fpadd16(d20, d30);
              d0  = vis_fpadd16(d0,  d00);
              d0  = vis_fpadd16(d0,  d20);
              d01 = vis_fpadd16(d01, d11);
              d21 = vis_fpadd16(d21, d31);
              d1  = vis_fpadd16(d1,  d01);
              d1  = vis_fpadd16(d1,  d21);
              buffd[2*i] = d0;
              buffd[2*i + 1] = d1;
            }

          } else if (off == 4) {

            s01 = buff0[0];
            s11 = buff1[0];
            s21 = buff2[0];
            s31 = buff3[0];
#pragma pipeloop(0)
            for (i = 0; i < (xsize + 7)/8; i++) {
              d0 = buffd[2*i];
              d1 = buffd[2*i + 1];

              s00 = s01;
              s10 = s11;
              s20 = s21;
              s30 = s31;
              s01 = buff0[i + 1];
              s11 = buff1[i + 1];
              s21 = buff2[i + 1];
              s31 = buff3[i + 1];

              d00 = vis_fmul8x16au(vis_read_lo(s00), k0);
              d01 = vis_fmul8x16au(vis_read_hi(s01), k0);
              d10 = vis_fmul8x16au(vis_read_lo(s10), k1);
              d11 = vis_fmul8x16au(vis_read_hi(s11), k1);
              d20 = vis_fmul8x16au(vis_read_lo(s20), k2);
              d21 = vis_fmul8x16au(vis_read_hi(s21), k2);
              d30 = vis_fmul8x16au(vis_read_lo(s30), k3);
              d31 = vis_fmul8x16au(vis_read_hi(s31), k3);

              d00 = vis_fpadd16(d00, d10);
              d20 = vis_fpadd16(d20, d30);
              d0  = vis_fpadd16(d0,  d00);
              d0  = vis_fpadd16(d0,  d20);
              d01 = vis_fpadd16(d01, d11);
              d21 = vis_fpadd16(d21, d31);
              d1  = vis_fpadd16(d1,  d01);
              d1  = vis_fpadd16(d1,  d21);
              buffd[2*i] = d0;
              buffd[2*i + 1] = d1;
            }

          } else {

            s01 = buff0[0];
            s11 = buff1[0];
            s21 = buff2[0];
            s31 = buff3[0];
#pragma pipeloop(0)
            for (i = 0; i < (xsize + 7)/8; i++) {
              d0 = buffd[2*i];
              d1 = buffd[2*i + 1];

              s00 = s01;
              s10 = s11;
              s20 = s21;
              s30 = s31;
              s01 = buff0[i + 1];
              s11 = buff1[i + 1];
              s21 = buff2[i + 1];
              s31 = buff3[i + 1];
              s0  = vis_faligndata(s00, s01);
              s1  = vis_faligndata(s10, s11);
              s2  = vis_faligndata(s20, s21);
              s3  = vis_faligndata(s30, s31);

              d00 = vis_fmul8x16au(vis_read_hi(s0), k0);
              d01 = vis_fmul8x16au(vis_read_lo(s0), k0);
              d10 = vis_fmul8x16au(vis_read_hi(s1), k1);
              d11 = vis_fmul8x16au(vis_read_lo(s1), k1);
              d20 = vis_fmul8x16au(vis_read_hi(s2), k2);
              d21 = vis_fmul8x16au(vis_read_lo(s2), k2);
              d30 = vis_fmul8x16au(vis_read_hi(s3), k3);
              d31 = vis_fmul8x16au(vis_read_lo(s3), k3);

              d00 = vis_fpadd16(d00, d10);
              d20 = vis_fpadd16(d20, d30);
              d0  = vis_fpadd16(d0,  d00);
              d0  = vis_fpadd16(d0,  d20);
              d01 = vis_fpadd16(d01, d11);
              d21 = vis_fpadd16(d21, d31);
              d1  = vis_fpadd16(d1,  d01);
              d1  = vis_fpadd16(d1,  d21);
              buffd[2*i] = d0;
              buffd[2*i + 1] = d1;
            }
          }
        }

        pk += 4*m;
      }
    }

    /*****************************************
     *****************************************
     **          Final iteration            **
     *****************************************
     *****************************************/

    jk_size = n;
#ifdef CONV_INDEX
    if (jk_size >= 5) jk_size = 3;
    if (jk_size == 4) jk_size = 2;
#else
    if (jk_size >= 6) jk_size = 4;
    if (jk_size == 5) jk_size = 3;
#endif

    k0 = karr[ik_last];
    k1 = karr[ik_last + m];
    k2 = karr[ik_last + 2*m];
    k3 = karr[ik_last + 3*m];

    off  = ik_last*NCHAN;
    doff = off/8;
    off &= 7;
    buff0 = buff[0] + doff;
    buff1 = buff[1] + doff;
    buff2 = buff[2] + doff;
    buff3 = buff[3] + doff;
    vis_write_gsr(gsr_scale + off);

#ifndef CONV_INDEX
    if (jk_size == 2) {
      dp = ((mlib_addr)dl & 7) ? buffe : (mlib_d64*)dl;

      s01 = buff0[0];
      s11 = buff1[0];
#pragma pipeloop(0)
      for (i = 0; i < xsize/8; i++) {
        s00 = s01;
        s10 = s11;
        s01 = buff0[i + 1];
        s11 = buff1[i + 1];
        s0  = vis_faligndata(s00, s01);
        s1  = vis_faligndata(s10, s11);

        d00 = vis_fmul8x16au(vis_read_hi(s0), k0);
        d01 = vis_fmul8x16au(vis_read_lo(s0), k0);
        d10 = vis_fmul8x16au(vis_read_hi(s1), k1);
        d11 = vis_fmul8x16au(vis_read_lo(s1), k1);

        d0 = buffd[2*i];
        d1 = buffd[2*i + 1];
        d0 = vis_fpadd16(d0, d00);
        d0 = vis_fpadd16(d0, d10);
        d1 = vis_fpadd16(d1, d01);
        d1 = vis_fpadd16(d1, d11);

        dd = vis_fpack16_pair(d0, d1);
        dp[i] = dd;

        buffd[2*i    ] = drnd;
        buffd[2*i + 1] = drnd;
      }

      if (emask) {
        s00 = s01;
        s10 = s11;
        s01 = buff0[i + 1];
        s11 = buff1[i + 1];
        s0  = vis_faligndata(s00, s01);
        s1  = vis_faligndata(s10, s11);

        d00 = vis_fmul8x16au(vis_read_hi(s0), k0);
        d01 = vis_fmul8x16au(vis_read_lo(s0), k0);
        d10 = vis_fmul8x16au(vis_read_hi(s1), k1);
        d11 = vis_fmul8x16au(vis_read_lo(s1), k1);

        d0 = buffd[2*i];
        d1 = buffd[2*i + 1];
        d0 = vis_fpadd16(d0, d00);
        d0 = vis_fpadd16(d0, d10);
        d1 = vis_fpadd16(d1, d01);
        d1 = vis_fpadd16(d1, d11);

        dd = vis_fpack16_pair(d0, d1);
        vis_pst_8(dd, dp + i, emask);

        buffd[2*i    ] = drnd;
        buffd[2*i + 1] = drnd;
      }

      if ((mlib_u8*)dp != dl) mlib_ImageCopy_na((void*)buffe, dl, xsize);

    } else if (jk_size == 3) {

      dp = ((mlib_addr)dl & 7) ? buffe : (mlib_d64*)dl;

      s01 = buff0[0];
      s11 = buff1[0];
      s21 = buff2[0];
#pragma pipeloop(0)
      for (i = 0; i < xsize/8; i++) {
        s00 = s01;
        s10 = s11;
        s20 = s21;
        s01 = buff0[i + 1];
        s11 = buff1[i + 1];
        s21 = buff2[i + 1];
        s0  = vis_faligndata(s00, s01);
        s1  = vis_faligndata(s10, s11);
        s2  = vis_faligndata(s20, s21);

        d00 = vis_fmul8x16au(vis_read_hi(s0), k0);
        d01 = vis_fmul8x16au(vis_read_lo(s0), k0);
        d10 = vis_fmul8x16au(vis_read_hi(s1), k1);
        d11 = vis_fmul8x16au(vis_read_lo(s1), k1);
        d20 = vis_fmul8x16au(vis_read_hi(s2), k2);
        d21 = vis_fmul8x16au(vis_read_lo(s2), k2);

        d0 = buffd[2*i];
        d1 = buffd[2*i + 1];
        d0 = vis_fpadd16(d0, d00);
        d0 = vis_fpadd16(d0, d10);
        d0 = vis_fpadd16(d0, d20);
        d1 = vis_fpadd16(d1, d01);
        d1 = vis_fpadd16(d1, d11);
        d1 = vis_fpadd16(d1, d21);

        dd = vis_fpack16_pair(d0, d1);
        dp[i] = dd;

        buffd[2*i    ] = drnd;
        buffd[2*i + 1] = drnd;
      }

      if (emask) {
        s00 = s01;
        s10 = s11;
        s20 = s21;
        s01 = buff0[i + 1];
        s11 = buff1[i + 1];
        s21 = buff2[i + 1];
        s0  = vis_faligndata(s00, s01);
        s1  = vis_faligndata(s10, s11);
        s2  = vis_faligndata(s20, s21);

        d00 = vis_fmul8x16au(vis_read_hi(s0), k0);
        d01 = vis_fmul8x16au(vis_read_lo(s0), k0);
        d10 = vis_fmul8x16au(vis_read_hi(s1), k1);
        d11 = vis_fmul8x16au(vis_read_lo(s1), k1);
        d20 = vis_fmul8x16au(vis_read_hi(s2), k2);
        d21 = vis_fmul8x16au(vis_read_lo(s2), k2);

        d0 = buffd[2*i];
        d1 = buffd[2*i + 1];
        d0 = vis_fpadd16(d0, d00);
        d0 = vis_fpadd16(d0, d10);
        d0 = vis_fpadd16(d0, d20);
        d1 = vis_fpadd16(d1, d01);
        d1 = vis_fpadd16(d1, d11);
        d1 = vis_fpadd16(d1, d21);

        dd = vis_fpack16_pair(d0, d1);
        vis_pst_8(dd, dp + i, emask);

        buffd[2*i    ] = drnd;
        buffd[2*i + 1] = drnd;
      }

      if ((mlib_u8*)dp != dl) mlib_ImageCopy_na((void*)buffe, dl, xsize);

    } else /* if (jk_size == 4) */ {

      dp = ((mlib_addr)dl & 7) ? buffe : (mlib_d64*)dl;

      s01 = buff0[0];
      s11 = buff1[0];
      s21 = buff2[0];
      s31 = buff3[0];
#pragma pipeloop(0)
      for (i = 0; i < xsize/8; i++) {
        s00 = s01;
        s10 = s11;
        s20 = s21;
        s30 = s31;
        s01 = buff0[i + 1];
        s11 = buff1[i + 1];
        s21 = buff2[i + 1];
        s31 = buff3[i + 1];
        s0  = vis_faligndata(s00, s01);
        s1  = vis_faligndata(s10, s11);
        s2  = vis_faligndata(s20, s21);
        s3  = vis_faligndata(s30, s31);

        d00 = vis_fmul8x16au(vis_read_hi(s0), k0);
        d01 = vis_fmul8x16au(vis_read_lo(s0), k0);
        d10 = vis_fmul8x16au(vis_read_hi(s1), k1);
        d11 = vis_fmul8x16au(vis_read_lo(s1), k1);
        d20 = vis_fmul8x16au(vis_read_hi(s2), k2);
        d21 = vis_fmul8x16au(vis_read_lo(s2), k2);
        d30 = vis_fmul8x16au(vis_read_hi(s3), k3);
        d31 = vis_fmul8x16au(vis_read_lo(s3), k3);

        d0 = buffd[2*i];
        d1 = buffd[2*i + 1];
        d0 = vis_fpadd16(d0, d00);
        d0 = vis_fpadd16(d0, d10);
        d0 = vis_fpadd16(d0, d20);
        d0 = vis_fpadd16(d0, d30);
        d1 = vis_fpadd16(d1, d01);
        d1 = vis_fpadd16(d1, d11);
        d1 = vis_fpadd16(d1, d21);
        d1 = vis_fpadd16(d1, d31);

        dd = vis_fpack16_pair(d0, d1);
        dp[i] = dd;

        buffd[2*i    ] = drnd;
        buffd[2*i + 1] = drnd;
      }

      if (emask) {
        s00 = s01;
        s10 = s11;
        s20 = s21;
        s30 = s31;
        s01 = buff0[i + 1];
        s11 = buff1[i + 1];
        s21 = buff2[i + 1];
        s31 = buff3[i + 1];
        s0  = vis_faligndata(s00, s01);
        s1  = vis_faligndata(s10, s11);
        s2  = vis_faligndata(s20, s21);
        s3  = vis_faligndata(s30, s31);

        d00 = vis_fmul8x16au(vis_read_hi(s0), k0);
        d01 = vis_fmul8x16au(vis_read_lo(s0), k0);
        d10 = vis_fmul8x16au(vis_read_hi(s1), k1);
        d11 = vis_fmul8x16au(vis_read_lo(s1), k1);
        d20 = vis_fmul8x16au(vis_read_hi(s2), k2);
        d21 = vis_fmul8x16au(vis_read_lo(s2), k2);
        d30 = vis_fmul8x16au(vis_read_hi(s3), k3);
        d31 = vis_fmul8x16au(vis_read_lo(s3), k3);

        d0 = buffd[2*i];
        d1 = buffd[2*i + 1];
        d0 = vis_fpadd16(d0, d00);
        d0 = vis_fpadd16(d0, d10);
        d0 = vis_fpadd16(d0, d20);
        d0 = vis_fpadd16(d0, d30);
        d1 = vis_fpadd16(d1, d01);
        d1 = vis_fpadd16(d1, d11);
        d1 = vis_fpadd16(d1, d21);
        d1 = vis_fpadd16(d1, d31);

        dd = vis_fpack16_pair(d0, d1);
        vis_pst_8(dd, dp + i, emask);

        buffd[2*i    ] = drnd;
        buffd[2*i + 1] = drnd;
      }

      if ((mlib_u8*)dp != dl) mlib_ImageCopy_na((void*)buffe, dl, xsize);
    }

#else /* CONV_INDEX */

    if (jk_size == 2) {
      vis_write_gsr(gsr_scale + 7);

#pragma pipeloop(0)
      for (i = 0; i < dsize; i += 3) {
        mlib_d64 d00, d01, d02, d03, d04, d05;
        mlib_d64 d10, d11, d12, d13, d14, d15;
        mlib_d64 d0, d1, d2, d3, d4, d5;
        mlib_d64 s00 = buff0[i];
        mlib_d64 s01 = buff0[i + 1];
        mlib_d64 s02 = buff0[i + 2];
        mlib_d64 s10 = buff1[i];
        mlib_d64 s11 = buff1[i + 1];
        mlib_d64 s12 = buff1[i + 2];

        d00 = vis_fmul8x16au(vis_read_hi(s00), k0);
        d01 = vis_fmul8x16au(vis_read_lo(s00), k0);
        d02 = vis_fmul8x16au(vis_read_hi(s01), k0);
        d03 = vis_fmul8x16au(vis_read_lo(s01), k0);
        d04 = vis_fmul8x16au(vis_read_hi(s02), k0);
        d05 = vis_fmul8x16au(vis_read_lo(s02), k0);
        d10 = vis_fmul8x16au(vis_read_hi(s10), k1);
        d11 = vis_fmul8x16au(vis_read_lo(s10), k1);
        d12 = vis_fmul8x16au(vis_read_hi(s11), k1);
        d13 = vis_fmul8x16au(vis_read_lo(s11), k1);
        d14 = vis_fmul8x16au(vis_read_hi(s12), k1);
        d15 = vis_fmul8x16au(vis_read_lo(s12), k1);

        d0 = buffd[2*i];
        d1 = buffd[2*i + 1];
        d2 = buffd[2*i + 2];
        d3 = buffd[2*i + 3];
        d4 = buffd[2*i + 4];
        d5 = buffd[2*i + 5];
        d0 = vis_fpadd16(d0, d00);
        d0 = vis_fpadd16(d0, d10);
        d1 = vis_fpadd16(d1, d01);
        d1 = vis_fpadd16(d1, d11);
        d2 = vis_fpadd16(d2, d02);
        d2 = vis_fpadd16(d2, d12);
        d3 = vis_fpadd16(d3, d03);
        d3 = vis_fpadd16(d3, d13);
        d4 = vis_fpadd16(d4, d04);
        d4 = vis_fpadd16(d4, d14);
        d5 = vis_fpadd16(d5, d05);
        d5 = vis_fpadd16(d5, d15);

        buffe[i    ] = vis_fpack16_pair(d0, d1);
        buffe[i + 1] = vis_fpack16_pair(d2, d3);
        buffe[i + 2] = vis_fpack16_pair(d4, d5);

        buffd[2*i    ] = drnd;
        buffd[2*i + 1] = drnd;
        buffd[2*i + 2] = drnd;
        buffd[2*i + 3] = drnd;
        buffd[2*i + 4] = drnd;
        buffd[2*i + 5] = drnd;

        LOAD_SRC();
      }

    } else /* if (jk_size == 3) */ {
      vis_write_gsr(gsr_scale + 7);

#pragma pipeloop(0)
      for (i = 0; i < dsize; i += 3) {
        mlib_d64 d00, d01, d02, d03, d04, d05;
        mlib_d64 d10, d11, d12, d13, d14, d15;
        mlib_d64 d20, d21, d22, d23, d24, d25;
        mlib_d64 d0, d1, d2, d3, d4, d5;
        mlib_d64 s00 = buff0[i];
        mlib_d64 s01 = buff0[i + 1];
        mlib_d64 s02 = buff0[i + 2];
        mlib_d64 s10 = buff1[i];
        mlib_d64 s11 = buff1[i + 1];
        mlib_d64 s12 = buff1[i + 2];
        mlib_d64 s20 = buff2[i];
        mlib_d64 s21 = buff2[i + 1];
        mlib_d64 s22 = buff2[i + 2];

        d00 = vis_fmul8x16au(vis_read_hi(s00), k0);
        d01 = vis_fmul8x16au(vis_read_lo(s00), k0);
        d02 = vis_fmul8x16au(vis_read_hi(s01), k0);
        d03 = vis_fmul8x16au(vis_read_lo(s01), k0);
        d04 = vis_fmul8x16au(vis_read_hi(s02), k0);
        d05 = vis_fmul8x16au(vis_read_lo(s02), k0);
        d10 = vis_fmul8x16au(vis_read_hi(s10), k1);
        d11 = vis_fmul8x16au(vis_read_lo(s10), k1);
        d12 = vis_fmul8x16au(vis_read_hi(s11), k1);
        d13 = vis_fmul8x16au(vis_read_lo(s11), k1);
        d14 = vis_fmul8x16au(vis_read_hi(s12), k1);
        d15 = vis_fmul8x16au(vis_read_lo(s12), k1);
        d20 = vis_fmul8x16au(vis_read_hi(s20), k2);
        d21 = vis_fmul8x16au(vis_read_lo(s20), k2);
        d22 = vis_fmul8x16au(vis_read_hi(s21), k2);
        d23 = vis_fmul8x16au(vis_read_lo(s21), k2);
        d24 = vis_fmul8x16au(vis_read_hi(s22), k2);
        d25 = vis_fmul8x16au(vis_read_lo(s22), k2);

        d0 = buffd[2*i];
        d1 = buffd[2*i + 1];
        d2 = buffd[2*i + 2];
        d3 = buffd[2*i + 3];
        d4 = buffd[2*i + 4];
        d5 = buffd[2*i + 5];
        d0 = vis_fpadd16(d0, d00);
        d0 = vis_fpadd16(d0, d10);
        d0 = vis_fpadd16(d0, d20);
        d1 = vis_fpadd16(d1, d01);
        d1 = vis_fpadd16(d1, d11);
        d1 = vis_fpadd16(d1, d21);
        d2 = vis_fpadd16(d2, d02);
        d2 = vis_fpadd16(d2, d12);
        d2 = vis_fpadd16(d2, d22);
        d3 = vis_fpadd16(d3, d03);
        d3 = vis_fpadd16(d3, d13);
        d3 = vis_fpadd16(d3, d23);
        d4 = vis_fpadd16(d4, d04);
        d4 = vis_fpadd16(d4, d14);
        d4 = vis_fpadd16(d4, d24);
        d5 = vis_fpadd16(d5, d05);
        d5 = vis_fpadd16(d5, d15);
        d5 = vis_fpadd16(d5, d25);

        buffe[i    ] = vis_fpack16_pair(d0, d1);
        buffe[i + 1] = vis_fpack16_pair(d2, d3);
        buffe[i + 2] = vis_fpack16_pair(d4, d5);

        buffd[2*i    ] = drnd;
        buffd[2*i + 1] = drnd;
        buffd[2*i + 2] = drnd;
        buffd[2*i + 3] = drnd;
        buffd[2*i + 4] = drnd;
        buffd[2*i + 5] = drnd;

        LOAD_SRC();
      }
    }
#endif /* CONV_INDEX */

#ifdef CONV_INDEX
    mlib_ImageColorTrue2IndexLine_U8_U8_3((void*)buffe, dl, wid, colormap);
#endif /* CONV_INDEX */

    sl += sll;
    dl += dll;

    buff_ind++;
    if (buff_ind >= (n + 1)) buff_ind = 0;
  }

  mlib_free(pbuff);
  if (buffs != buffs_local) mlib_free(buffs);

  return MLIB_SUCCESS;
}