syoyo/tinyexr

Duplicated code in DecompressZip and DecompressRLE

jeffatrad opened this issue · 2 comments

There is a chunk of code at the end of both decompresszip and decompressrle that is just cut and pasted.

If you split this out into and undo_predictor and undo_reorder and then just call them, and then do a little IPC unrolling, this will simplify the code and run about 10% faster for 4K RLE loads:

static void undo_predictor( unsigned char * t, unsigned long uncompressed_size )
{
    unsigned char *stop = t + uncompressed_size;
    int tm1 = 128;

    if ( uncompressed_size >= 16 ) // for some minimum size
    {
      unsigned char *stop4 = t + (uncompressed_size&~3);
      while (t < stop4) {
        int t0 = t[0];
        int t1 = t[1];
        int t2 = t[2];
        int t3 = t[3];

        t[0] = static_cast<unsigned char>(tm1+t0-128);
        t[1] = static_cast<unsigned char>(tm1+t0-128+t1-128);
        t[2] = static_cast<unsigned char>(tm1+t0-128+t1-128+t2-128);
        t[3] = tm1 = static_cast<unsigned char>(tm1+t0-128+t1-128+t2-128+t3-128);

        t += 4;
      }
    }

    while (t < stop) {
      int d = tm1 + int(t[0]) - 128;
      t[0] = tm1 = static_cast<unsigned char>(d);
      ++t;
    }
}

static void undo_reorder( unsigned char *dst, unsigned char *t, unsigned long uncompressed_size )
{
  const char *t1 = reinterpret_cast<const char *>(t);
  const char *t2 = reinterpret_cast<const char *>(t) +
                   (uncompressed_size + 1) / 2;
  char *s = reinterpret_cast<char *>(dst);
  char *stop = s + (uncompressed_size);
  char *stop8 = s + (uncompressed_size&~7);

  while( s < stop8 )
  {
    s[0]=t1[0];
    s[1]=t2[0];
    s[2]=t1[1];
    s[3]=t2[1];
    s[4]=t1[2];
    s[5]=t2[2];
    s[6]=t1[3];
    s[7]=t2[3];
    t1 += 4;
    t2 += 4;
    s += 8;
  }

  for (;;) {
    if (s < stop)
      *(s++) = *(t1++);
    else
      break;
    if (s < stop)
      *(s++) = *(t2++);
    else
      break;
  }
}

Even if you don't do initial unrolled loop, it would be good to deduplicate this code.

Thanks!

syoyo commented

Please send PR of this change.

syoyo commented

Close the issue since there is no PR has been submitted