Blame libdjvu/IW44Image.cpp

Packit df99a1
//C-  -*- C++ -*-
Packit df99a1
//C- -------------------------------------------------------------------
Packit df99a1
//C- DjVuLibre-3.5
Packit df99a1
//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
Packit df99a1
//C- Copyright (c) 2001  AT&T
Packit df99a1
//C-
Packit df99a1
//C- This software is subject to, and may be distributed under, the
Packit df99a1
//C- GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- or (at your option) any later version. The license should have
Packit df99a1
//C- accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C-
Packit df99a1
//C- This program is distributed in the hope that it will be useful,
Packit df99a1
//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit df99a1
//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit df99a1
//C- GNU General Public License for more details.
Packit df99a1
//C- 
Packit df99a1
//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from
Packit df99a1
//C- Lizardtech Software.  Lizardtech Software has authorized us to
Packit df99a1
//C- replace the original DjVu(r) Reference Library notice by the following
Packit df99a1
//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu):
Packit df99a1
//C-
Packit df99a1
//C-  ------------------------------------------------------------------
Packit df99a1
//C- | DjVu (r) Reference Library (v. 3.5)
Packit df99a1
//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
Packit df99a1
//C- | The DjVu Reference Library is protected by U.S. Pat. No.
Packit df99a1
//C- | 6,058,214 and patents pending.
Packit df99a1
//C- |
Packit df99a1
//C- | This software is subject to, and may be distributed under, the
Packit df99a1
//C- | GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- | or (at your option) any later version. The license should have
Packit df99a1
//C- | accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- | from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C- |
Packit df99a1
//C- | The computer code originally released by LizardTech under this
Packit df99a1
//C- | license and unmodified by other parties is deemed "the LIZARDTECH
Packit df99a1
//C- | ORIGINAL CODE."  Subject to any third party intellectual property
Packit df99a1
//C- | claims, LizardTech grants recipient a worldwide, royalty-free, 
Packit df99a1
//C- | non-exclusive license to make, use, sell, or otherwise dispose of 
Packit df99a1
//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 
Packit df99a1
//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 
Packit df99a1
//C- | General Public License.   This grant only confers the right to 
Packit df99a1
//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 
Packit df99a1
//C- | the extent such infringement is reasonably necessary to enable 
Packit df99a1
//C- | recipient to make, have made, practice, sell, or otherwise dispose 
Packit df99a1
//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 
Packit df99a1
//C- | any greater extent that may be necessary to utilize further 
Packit df99a1
//C- | modifications or combinations.
Packit df99a1
//C- |
Packit df99a1
//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
Packit df99a1
//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
Packit df99a1
//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
Packit df99a1
//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Packit df99a1
//C- +------------------------------------------------------------------
Packit df99a1
Packit df99a1
#ifdef HAVE_CONFIG_H
Packit df99a1
# include "config.h"
Packit df99a1
#endif
Packit df99a1
#if NEED_GNUG_PRAGMAS
Packit df99a1
# pragma implementation
Packit df99a1
#endif
Packit df99a1
Packit df99a1
// - Author: Leon Bottou, 08/1998
Packit df99a1
Packit df99a1
// From: Leon Bottou, 1/31/2002
Packit df99a1
// Lizardtech has split this file into a decoder and an encoder.
Packit df99a1
// Only superficial changes.  The meat is mine.
Packit df99a1
Packit df99a1
#define IW44IMAGE_IMPLIMENTATION /* */
Packit df99a1
// -------------------^  not my spelling mistake (Leon Bottou)
Packit df99a1
Packit df99a1
#include "IW44Image.h"
Packit df99a1
#include "ZPCodec.h"
Packit df99a1
#include "GBitmap.h"
Packit df99a1
#include "GPixmap.h"
Packit df99a1
#include "IFFByteStream.h"
Packit df99a1
#include "GRect.h"
Packit df99a1
Packit df99a1
#include <stddef.h>
Packit df99a1
#include <stdlib.h>
Packit df99a1
#include <string.h>
Packit df99a1
#include <math.h>
Packit df99a1
#include "MMX.h"
Packit df99a1
#undef IWTRANSFORM_TIMER
Packit df99a1
#ifdef IWTRANSFORM_TIMER
Packit df99a1
#include "GOS.h"
Packit df99a1
#endif
Packit df99a1
Packit df99a1
#include <assert.h>
Packit df99a1
#include <string.h>
Packit df99a1
#include <math.h>
Packit df99a1
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
namespace DJVU {
Packit df99a1
# ifdef NOT_DEFINED // Just to fool emacs c++ mode
Packit df99a1
}
Packit df99a1
#endif
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
#define IWALLOCSIZE    4080
Packit df99a1
#define IWCODEC_MAJOR     1
Packit df99a1
#define IWCODEC_MINOR     2
Packit df99a1
#define DECIBEL_PRUNE   5.0
Packit df99a1
Packit df99a1
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
// WAVELET DECOMPOSITION CONSTANTS
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
Packit df99a1
// Parameters for IW44 wavelet.
Packit df99a1
// - iw_quant: quantization for all 16 sub-bands
Packit df99a1
// - iw_norm: norm of all wavelets (for db estimation)
Packit df99a1
// - iw_border: pixel border required to run filters
Packit df99a1
// - iw_shift: scale applied before decomposition
Packit df99a1
Packit df99a1
Packit df99a1
static const int iw_quant[16] = {
Packit df99a1
  0x004000, 
Packit df99a1
  0x008000, 0x008000, 0x010000,
Packit df99a1
  0x010000, 0x010000, 0x020000,
Packit df99a1
  0x020000, 0x020000, 0x040000,
Packit df99a1
  0x040000, 0x040000, 0x080000, 
Packit df99a1
  0x040000, 0x040000, 0x080000
Packit df99a1
};
Packit df99a1
Packit df99a1
static const float iw_norm[16] = {
Packit df99a1
  2.627989e+03F,
Packit df99a1
  1.832893e+02F, 1.832959e+02F, 5.114690e+01F,
Packit df99a1
  4.583344e+01F, 4.583462e+01F, 1.279225e+01F,
Packit df99a1
  1.149671e+01F, 1.149712e+01F, 3.218888e+00F,
Packit df99a1
  2.999281e+00F, 2.999476e+00F, 8.733161e-01F,
Packit df99a1
  1.074451e+00F, 1.074511e+00F, 4.289318e-01F
Packit df99a1
};
Packit df99a1
Packit df99a1
static const int iw_border = 3;
Packit df99a1
static const int iw_shift  = 6;
Packit df99a1
static const int iw_round  = (1<<(iw_shift-1));
Packit df99a1
Packit df99a1
class IW44Image::Codec::Decode : public IW44Image::Codec 
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  // Construction
Packit df99a1
  Decode(IW44Image::Map &map) : Codec(map) {}
Packit df99a1
  // Coding
Packit df99a1
  virtual int code_slice(ZPCodec &zp;;
Packit df99a1
};
Packit df99a1
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
// MMX IMPLEMENTATION HELPERS
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
Packit df99a1
Packit df99a1
// Note:
Packit df99a1
// MMX implementation for vertical transforms only.
Packit df99a1
// Speedup is basically related to faster memory transfer
Packit df99a1
// The IW44 transform is not CPU bound, it is memory bound.
Packit df99a1
Packit df99a1
#ifdef MMX
Packit df99a1
Packit df99a1
static const short w9[]  = {9,9,9,9};
Packit df99a1
static const short w1[]  = {1,1,1,1};
Packit df99a1
static const int   d8[]  = {8,8};
Packit df99a1
static const int   d16[] = {16,16};
Packit df99a1
Packit df99a1
static void
Packit df99a1
mmx_bv_1 ( short* &q, short* e, int s, int s3 )
Packit df99a1
{
Packit df99a1
  while (q
Packit df99a1
    {
Packit df99a1
      int a = (int)q[-s] + (int)q[s];
Packit df99a1
      int b = (int)q[-s3] + (int)q[s3];
Packit df99a1
      *q -= (((a<<3)+a-b+16)>>5);
Packit df99a1
      q ++;
Packit df99a1
  }
Packit df99a1
  while (q+3 < e)
Packit df99a1
    {
Packit df99a1
      MMXar( movq,       q-s,mm0);  // MM0=[ b3, b2, b1, b0 ]
Packit df99a1
      MMXar( movq,       q+s,mm2);  // MM2=[ c3, c2, c1, c0 ]
Packit df99a1
      MMXrr( movq,       mm0,mm1);  
Packit df99a1
      MMXrr( punpcklwd,  mm2,mm0);  // MM0=[ c1, b1, c0, b0 ]
Packit df99a1
      MMXrr( punpckhwd,  mm2,mm1);  // MM1=[ c3, b3, c2, b2 ]
Packit df99a1
      MMXar( pmaddwd,    w9,mm0);   // MM0=[ (c1+b1)*9, (c0+b0)*9 ]
Packit df99a1
      MMXar( pmaddwd,    w9,mm1);   // MM1=[ (c3+b3)*9, (c2+b2)*9 ]
Packit df99a1
      MMXar( movq,       q-s3,mm2);
Packit df99a1
      MMXar( movq,       q+s3,mm4);
Packit df99a1
      MMXrr( movq,       mm2,mm3);
Packit df99a1
      MMXrr( punpcklwd,  mm4,mm2);  // MM2=[ d1, a1, d0, a0 ]
Packit df99a1
      MMXrr( punpckhwd,  mm4,mm3);  // MM3=[ d3, a3, d2, a2 ]
Packit df99a1
      MMXar( pmaddwd,    w1,mm2);   // MM2=[ (a1+d1)*1, (a0+d0)*1 ]
Packit df99a1
      MMXar( pmaddwd,    w1,mm3);   // MM3=[ (a3+d3)*1, (a2+d2)*1 ]
Packit df99a1
      MMXar( paddd,      d16,mm0);
Packit df99a1
      MMXar( paddd,      d16,mm1);
Packit df99a1
      MMXrr( psubd,      mm2,mm0);  // MM0=[ (c1+b1)*9-a1-d1+8, ...
Packit df99a1
      MMXrr( psubd,      mm3,mm1);  // MM1=[ (c3+b3)*9-a3-d3+8, ...
Packit df99a1
      MMXir( psrad,      5,mm0);
Packit df99a1
      MMXar( movq,       q,mm7);    // MM7=[ p3,p2,p1,p0 ]
Packit df99a1
      MMXir( psrad,      5,mm1);
Packit df99a1
      MMXrr( packssdw,   mm1,mm0);  // MM0=[ x3,x2,x1,x0 ]
Packit df99a1
      MMXrr( psubw,      mm0,mm7);  // MM7=[ p3-x3, p2-x2, ... ]
Packit df99a1
      MMXra( movq,       mm7,q);
Packit df99a1
#if defined(_MSC_VER) && defined(_DEBUG)
Packit df99a1
      MMXemms;
Packit df99a1
#endif
Packit df99a1
      q += 4;
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
static void
Packit df99a1
mmx_bv_2 ( short* &q, short* e, int s, int s3 )
Packit df99a1
{
Packit df99a1
  while (q
Packit df99a1
    {
Packit df99a1
      int a = (int)q[-s] + (int)q[s];
Packit df99a1
      int b = (int)q[-s3] + (int)q[s3];
Packit df99a1
      *q += (((a<<3)+a-b+8)>>4);
Packit df99a1
      q ++;
Packit df99a1
    }
Packit df99a1
  while (q+3 < e)
Packit df99a1
    {
Packit df99a1
      MMXar( movq,       q-s,mm0);  // MM0=[ b3, b2, b1, b0 ]
Packit df99a1
      MMXar( movq,       q+s,mm2);  // MM2=[ c3, c2, c1, c0 ]
Packit df99a1
      MMXrr( movq,       mm0,mm1);  
Packit df99a1
      MMXrr( punpcklwd,  mm2,mm0);  // MM0=[ c1, b1, c0, b0 ]
Packit df99a1
      MMXrr( punpckhwd,  mm2,mm1);  // MM1=[ c3, b3, c2, b2 ]
Packit df99a1
      MMXar( pmaddwd,    w9,mm0);   // MM0=[ (c1+b1)*9, (c0+b0)*9 ]
Packit df99a1
      MMXar( pmaddwd,    w9,mm1);   // MM1=[ (c3+b3)*9, (c2+b2)*9 ]
Packit df99a1
      MMXar( movq,       q-s3,mm2);
Packit df99a1
      MMXar( movq,       q+s3,mm4);
Packit df99a1
      MMXrr( movq,       mm2,mm3);
Packit df99a1
      MMXrr( punpcklwd,  mm4,mm2);  // MM2=[ d1, a1, d0, a0 ]
Packit df99a1
      MMXrr( punpckhwd,  mm4,mm3);  // MM3=[ d3, a3, d2, a2 ]
Packit df99a1
      MMXar( pmaddwd,    w1,mm2);   // MM2=[ (a1+d1)*1, (a0+d0)*1 ]
Packit df99a1
      MMXar( pmaddwd,    w1,mm3);   // MM3=[ (a3+d3)*1, (a2+d2)*1 ]
Packit df99a1
      MMXar( paddd,      d8,mm0);
Packit df99a1
      MMXar( paddd,      d8,mm1);
Packit df99a1
      MMXrr( psubd,      mm2,mm0);  // MM0=[ (c1+b1)*9-a1-d1+8, ...
Packit df99a1
      MMXrr( psubd,      mm3,mm1);  // MM1=[ (c3+b3)*9-a3-d3+8, ...
Packit df99a1
      MMXir( psrad,      4,mm0);
Packit df99a1
      MMXar( movq,       q,mm7);    // MM7=[ p3,p2,p1,p0 ]
Packit df99a1
      MMXir( psrad,      4,mm1);
Packit df99a1
      MMXrr( packssdw,   mm1,mm0);  // MM0=[ x3,x2,x1,x0 ]
Packit df99a1
      MMXrr( paddw,      mm0,mm7);  // MM7=[ p3+x3, p2+x2, ... ]
Packit df99a1
      MMXra( movq,       mm7,q);
Packit df99a1
#if defined(_MSC_VER) && defined(_DEBUG)
Packit df99a1
      MMXemms;
Packit df99a1
#endif
Packit df99a1
      q += 4;
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
#endif /* MMX */
Packit df99a1
Packit df99a1
static void 
Packit df99a1
filter_bv(short *p, int w, int h, int rowsize, int scale)
Packit df99a1
{
Packit df99a1
  int y = 0;
Packit df99a1
  int s = scale*rowsize;
Packit df99a1
  int s3 = s+s+s;
Packit df99a1
  h = ((h-1)/scale)+1;
Packit df99a1
  while (y-3 < h)
Packit df99a1
    {
Packit df99a1
      // 1-Lifting
Packit df99a1
      {
Packit df99a1
        short *q = p;
Packit df99a1
        short *e = q+w;
Packit df99a1
        if (y>=3 && y+3
Packit df99a1
          {
Packit df99a1
            // Generic case
Packit df99a1
#ifdef MMX
Packit df99a1
            if (scale==1 && MMXControl::mmxflag>0)
Packit df99a1
              mmx_bv_1(q, e, s, s3);
Packit df99a1
#endif
Packit df99a1
            while (q
Packit df99a1
              {
Packit df99a1
                int a = (int)q[-s] + (int)q[s];
Packit df99a1
                int b = (int)q[-s3] + (int)q[s3];
Packit df99a1
                *q -= (((a<<3)+a-b+16)>>5);
Packit df99a1
                q += scale;
Packit df99a1
              }
Packit df99a1
          }
Packit df99a1
        else if (y
Packit df99a1
          {
Packit df99a1
            // Special cases
Packit df99a1
            short *q1 = (y+1
Packit df99a1
            short *q3 = (y+3
Packit df99a1
            if (y>=3)
Packit df99a1
              {
Packit df99a1
                while (q
Packit df99a1
                  {
Packit df99a1
                    int a = (int)q[-s] + (q1 ? (int)(*q1) : 0);
Packit df99a1
                    int b = (int)q[-s3] + (q3 ? (int)(*q3) : 0);
Packit df99a1
                    *q -= (((a<<3)+a-b+16)>>5);
Packit df99a1
                    q += scale;
Packit df99a1
                    if (q1) q1 += scale;
Packit df99a1
                    if (q3) q3 += scale;
Packit df99a1
                  }
Packit df99a1
              }
Packit df99a1
            else if (y>=1)
Packit df99a1
              {
Packit df99a1
                while (q
Packit df99a1
                  {
Packit df99a1
                    int a = (int)q[-s] + (q1 ? (int)(*q1) : 0);
Packit df99a1
                    int b = (q3 ? (int)(*q3) : 0);
Packit df99a1
                    *q -= (((a<<3)+a-b+16)>>5);
Packit df99a1
                    q += scale;
Packit df99a1
                    if (q1) q1 += scale;
Packit df99a1
                    if (q3) q3 += scale;
Packit df99a1
                  }
Packit df99a1
              }
Packit df99a1
            else
Packit df99a1
              {
Packit df99a1
                while (q
Packit df99a1
                  {
Packit df99a1
                    int a = (q1 ? (int)(*q1) : 0);
Packit df99a1
                    int b = (q3 ? (int)(*q3) : 0);
Packit df99a1
                    *q -= (((a<<3)+a-b+16)>>5);
Packit df99a1
                    q += scale;
Packit df99a1
                    if (q1) q1 += scale;
Packit df99a1
                    if (q3) q3 += scale;
Packit df99a1
                  }
Packit df99a1
              }
Packit df99a1
          }
Packit df99a1
      }
Packit df99a1
      // 2-Interpolation
Packit df99a1
      {
Packit df99a1
        short *q = p-s3;
Packit df99a1
        short *e = q+w;
Packit df99a1
        if (y>=6 && y
Packit df99a1
          {
Packit df99a1
            // Generic case
Packit df99a1
#ifdef MMX
Packit df99a1
            if (scale==1 && MMXControl::mmxflag>0)
Packit df99a1
              mmx_bv_2(q, e, s, s3);
Packit df99a1
#endif
Packit df99a1
            while (q
Packit df99a1
              {
Packit df99a1
                int a = (int)q[-s] + (int)q[s];
Packit df99a1
                int b = (int)q[-s3] + (int)q[s3];
Packit df99a1
                *q += (((a<<3)+a-b+8)>>4);
Packit df99a1
                q += scale;
Packit df99a1
              }
Packit df99a1
          }
Packit df99a1
        else if (y>=3)
Packit df99a1
          {
Packit df99a1
            // Special cases
Packit df99a1
            short *q1 = (y-2
Packit df99a1
            while (q
Packit df99a1
              {
Packit df99a1
                int a = (int)q[-s] + (int)(*q1);
Packit df99a1
                *q += ((a+1)>>1);
Packit df99a1
                q += scale;
Packit df99a1
                q1 += scale;
Packit df99a1
              }
Packit df99a1
          }
Packit df99a1
      }
Packit df99a1
      y += 2;
Packit df99a1
      p += s+s;
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
static void 
Packit df99a1
filter_bh(short *p, int w, int h, int rowsize, int scale)
Packit df99a1
{
Packit df99a1
  int y = 0;
Packit df99a1
  int s = scale;
Packit df99a1
  int s3 = s+s+s;
Packit df99a1
  rowsize *= scale;
Packit df99a1
  while (y
Packit df99a1
    {
Packit df99a1
      short *q = p;
Packit df99a1
      short *e = p+w;
Packit df99a1
      int a0=0, a1=0, a2=0, a3=0;
Packit df99a1
      int b0=0, b1=0, b2=0, b3=0;
Packit df99a1
      if (q
Packit df99a1
        {
Packit df99a1
          // Special case:  x=0
Packit df99a1
          if (q+s < e)
Packit df99a1
            a2 = q[s];
Packit df99a1
          if (q+s3 < e)
Packit df99a1
            a3 = q[s3];
Packit df99a1
          b2 = b3 = q[0] - ((((a1+a2)<<3)+(a1+a2)-a0-a3+16) >> 5);
Packit df99a1
          q[0] = b3;
Packit df99a1
          q += s+s;
Packit df99a1
        }
Packit df99a1
      if (q
Packit df99a1
        {
Packit df99a1
          // Special case:  x=2
Packit df99a1
          a0 = a1;
Packit df99a1
          a1 = a2;
Packit df99a1
          a2 = a3;
Packit df99a1
          if (q+s3 < e)
Packit df99a1
            a3 = q[s3];
Packit df99a1
          b3 = q[0] - ((((a1+a2)<<3)+(a1+a2)-a0-a3+16) >> 5);
Packit df99a1
          q[0] = b3;
Packit df99a1
          q += s+s;
Packit df99a1
        }
Packit df99a1
      if (q
Packit df99a1
        {
Packit df99a1
          // Special case:  x=4
Packit df99a1
          b1 = b2;
Packit df99a1
          b2 = b3;
Packit df99a1
          a0 = a1;
Packit df99a1
          a1 = a2;
Packit df99a1
          a2 = a3;
Packit df99a1
          if (q+s3 < e)
Packit df99a1
            a3 = q[s3];
Packit df99a1
          b3 = q[0] - ((((a1+a2)<<3)+(a1+a2)-a0-a3+16) >> 5);
Packit df99a1
          q[0] = b3;
Packit df99a1
          q[-s3] = q[-s3] + ((b1+b2+1)>>1);
Packit df99a1
          q += s+s;
Packit df99a1
        }
Packit df99a1
      while (q+s3 < e)
Packit df99a1
        {
Packit df99a1
          // Generic case
Packit df99a1
          a0=a1; 
Packit df99a1
          a1=a2; 
Packit df99a1
          a2=a3;
Packit df99a1
          a3=q[s3];
Packit df99a1
          b0=b1; 
Packit df99a1
          b1=b2; 
Packit df99a1
          b2=b3;
Packit df99a1
          b3 = q[0] - ((((a1+a2)<<3)+(a1+a2)-a0-a3+16) >> 5);
Packit df99a1
          q[0] = b3;
Packit df99a1
          q[-s3] = q[-s3] + ((((b1+b2)<<3)+(b1+b2)-b0-b3+8) >> 4);
Packit df99a1
          q += s+s;
Packit df99a1
        }
Packit df99a1
      while (q < e)
Packit df99a1
        {
Packit df99a1
          // Special case:  w-3 <= x < w
Packit df99a1
          a0=a1;
Packit df99a1
          a1=a2; 
Packit df99a1
          a2=a3;
Packit df99a1
          a3=0;
Packit df99a1
          b0=b1; 
Packit df99a1
          b1=b2; 
Packit df99a1
          b2=b3;
Packit df99a1
          b3 = q[0] - ((((a1+a2)<<3)+(a1+a2)-a0-a3+16) >> 5);
Packit df99a1
          q[0] = b3;
Packit df99a1
          q[-s3] = q[-s3] + ((((b1+b2)<<3)+(b1+b2)-b0-b3+8) >> 4);
Packit df99a1
          q += s+s;
Packit df99a1
        }
Packit df99a1
      while (q-s3 < e)
Packit df99a1
        {
Packit df99a1
          // Special case  w <= x < w+3
Packit df99a1
          b0=b1; 
Packit df99a1
          b1=b2; 
Packit df99a1
          b2=b3;
Packit df99a1
          if (q-s3 >= p)
Packit df99a1
            q[-s3] = q[-s3] + ((b1+b2+1)>>1);
Packit df99a1
          q += s+s;
Packit df99a1
        }
Packit df99a1
      y += scale;
Packit df99a1
      p += rowsize;
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
// REPRESENTATION OF WAVELET DECOMPOSED IMAGES
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
//---------------------------------------------------------------
Packit df99a1
// Zig zag location in a 1024 liftblock.
Packit df99a1
// These numbers have been generated with the following program:
Packit df99a1
//
Packit df99a1
// int x=0, y=0;
Packit df99a1
// for (int i=0; i<5; i++) {
Packit df99a1
//   x = (x<<1) | (n&1;;  n >>= 1;
Packit df99a1
//   y = (y<<1) | (n&1;;  n >>= 1;
Packit df99a1
// }
Packit df99a1
Packit df99a1
Packit df99a1
static int zigzagloc[1024] = {
Packit df99a1
   0,  16, 512, 528,   8,  24, 520, 536, 256, 272, 768, 784, 264, 280, 776, 792,
Packit df99a1
   4,  20, 516, 532,  12,  28, 524, 540, 260, 276, 772, 788, 268, 284, 780, 796,
Packit df99a1
 128, 144, 640, 656, 136, 152, 648, 664, 384, 400, 896, 912, 392, 408, 904, 920,
Packit df99a1
 132, 148, 644, 660, 140, 156, 652, 668, 388, 404, 900, 916, 396, 412, 908, 924,
Packit df99a1
   2,  18, 514, 530,  10,  26, 522, 538, 258, 274, 770, 786, 266, 282, 778, 794,
Packit df99a1
   6,  22, 518, 534,  14,  30, 526, 542, 262, 278, 774, 790, 270, 286, 782, 798,
Packit df99a1
 130, 146, 642, 658, 138, 154, 650, 666, 386, 402, 898, 914, 394, 410, 906, 922,
Packit df99a1
 134, 150, 646, 662, 142, 158, 654, 670, 390, 406, 902, 918, 398, 414, 910, 926,
Packit df99a1
  64,  80, 576, 592,  72,  88, 584, 600, 320, 336, 832, 848, 328, 344, 840, 856,
Packit df99a1
  68,  84, 580, 596,  76,  92, 588, 604, 324, 340, 836, 852, 332, 348, 844, 860,
Packit df99a1
 192, 208, 704, 720, 200, 216, 712, 728, 448, 464, 960, 976, 456, 472, 968, 984,
Packit df99a1
 196, 212, 708, 724, 204, 220, 716, 732, 452, 468, 964, 980, 460, 476, 972, 988,
Packit df99a1
  66,  82, 578, 594,  74,  90, 586, 602, 322, 338, 834, 850, 330, 346, 842, 858,
Packit df99a1
  70,  86, 582, 598,  78,  94, 590, 606, 326, 342, 838, 854, 334, 350, 846, 862,
Packit df99a1
 194, 210, 706, 722, 202, 218, 714, 730, 450, 466, 962, 978, 458, 474, 970, 986,
Packit df99a1
 198, 214, 710, 726, 206, 222, 718, 734, 454, 470, 966, 982, 462, 478, 974, 990, // 255
Packit df99a1
   1,  17, 513, 529,   9,  25, 521, 537, 257, 273, 769, 785, 265, 281, 777, 793,
Packit df99a1
   5,  21, 517, 533,  13,  29, 525, 541, 261, 277, 773, 789, 269, 285, 781, 797,
Packit df99a1
 129, 145, 641, 657, 137, 153, 649, 665, 385, 401, 897, 913, 393, 409, 905, 921,
Packit df99a1
 133, 149, 645, 661, 141, 157, 653, 669, 389, 405, 901, 917, 397, 413, 909, 925,
Packit df99a1
   3,  19, 515, 531,  11,  27, 523, 539, 259, 275, 771, 787, 267, 283, 779, 795,
Packit df99a1
   7,  23, 519, 535,  15,  31, 527, 543, 263, 279, 775, 791, 271, 287, 783, 799,
Packit df99a1
 131, 147, 643, 659, 139, 155, 651, 667, 387, 403, 899, 915, 395, 411, 907, 923,
Packit df99a1
 135, 151, 647, 663, 143, 159, 655, 671, 391, 407, 903, 919, 399, 415, 911, 927,
Packit df99a1
  65,  81, 577, 593,  73,  89, 585, 601, 321, 337, 833, 849, 329, 345, 841, 857,
Packit df99a1
  69,  85, 581, 597,  77,  93, 589, 605, 325, 341, 837, 853, 333, 349, 845, 861,
Packit df99a1
 193, 209, 705, 721, 201, 217, 713, 729, 449, 465, 961, 977, 457, 473, 969, 985,
Packit df99a1
 197, 213, 709, 725, 205, 221, 717, 733, 453, 469, 965, 981, 461, 477, 973, 989,
Packit df99a1
  67,  83, 579, 595,  75,  91, 587, 603, 323, 339, 835, 851, 331, 347, 843, 859,
Packit df99a1
  71,  87, 583, 599,  79,  95, 591, 607, 327, 343, 839, 855, 335, 351, 847, 863,
Packit df99a1
 195, 211, 707, 723, 203, 219, 715, 731, 451, 467, 963, 979, 459, 475, 971, 987,
Packit df99a1
 199, 215, 711, 727, 207, 223, 719, 735, 455, 471, 967, 983, 463, 479, 975, 991, // 511
Packit df99a1
  32,  48, 544, 560,  40,  56, 552, 568, 288, 304, 800, 816, 296, 312, 808, 824,
Packit df99a1
  36,  52, 548, 564,  44,  60, 556, 572, 292, 308, 804, 820, 300, 316, 812, 828,
Packit df99a1
 160, 176, 672, 688, 168, 184, 680, 696, 416, 432, 928, 944, 424, 440, 936, 952,
Packit df99a1
 164, 180, 676, 692, 172, 188, 684, 700, 420, 436, 932, 948, 428, 444, 940, 956,
Packit df99a1
  34,  50, 546, 562,  42,  58, 554, 570, 290, 306, 802, 818, 298, 314, 810, 826,
Packit df99a1
  38,  54, 550, 566,  46,  62, 558, 574, 294, 310, 806, 822, 302, 318, 814, 830,
Packit df99a1
 162, 178, 674, 690, 170, 186, 682, 698, 418, 434, 930, 946, 426, 442, 938, 954,
Packit df99a1
 166, 182, 678, 694, 174, 190, 686, 702, 422, 438, 934, 950, 430, 446, 942, 958,
Packit df99a1
  96, 112, 608, 624, 104, 120, 616, 632, 352, 368, 864, 880, 360, 376, 872, 888,
Packit df99a1
 100, 116, 612, 628, 108, 124, 620, 636, 356, 372, 868, 884, 364, 380, 876, 892,
Packit df99a1
 224, 240, 736, 752, 232, 248, 744, 760, 480, 496, 992,1008, 488, 504,1000,1016,
Packit df99a1
 228, 244, 740, 756, 236, 252, 748, 764, 484, 500, 996,1012, 492, 508,1004,1020,
Packit df99a1
  98, 114, 610, 626, 106, 122, 618, 634, 354, 370, 866, 882, 362, 378, 874, 890,
Packit df99a1
 102, 118, 614, 630, 110, 126, 622, 638, 358, 374, 870, 886, 366, 382, 878, 894,
Packit df99a1
 226, 242, 738, 754, 234, 250, 746, 762, 482, 498, 994,1010, 490, 506,1002,1018,
Packit df99a1
 230, 246, 742, 758, 238, 254, 750, 766, 486, 502, 998,1014, 494, 510,1006,1022, // 767
Packit df99a1
  33,  49, 545, 561,  41,  57, 553, 569, 289, 305, 801, 817, 297, 313, 809, 825,
Packit df99a1
  37,  53, 549, 565,  45,  61, 557, 573, 293, 309, 805, 821, 301, 317, 813, 829,
Packit df99a1
 161, 177, 673, 689, 169, 185, 681, 697, 417, 433, 929, 945, 425, 441, 937, 953,
Packit df99a1
 165, 181, 677, 693, 173, 189, 685, 701, 421, 437, 933, 949, 429, 445, 941, 957,
Packit df99a1
  35,  51, 547, 563,  43,  59, 555, 571, 291, 307, 803, 819, 299, 315, 811, 827,
Packit df99a1
  39,  55, 551, 567,  47,  63, 559, 575, 295, 311, 807, 823, 303, 319, 815, 831,
Packit df99a1
 163, 179, 675, 691, 171, 187, 683, 699, 419, 435, 931, 947, 427, 443, 939, 955,
Packit df99a1
 167, 183, 679, 695, 175, 191, 687, 703, 423, 439, 935, 951, 431, 447, 943, 959,
Packit df99a1
  97, 113, 609, 625, 105, 121, 617, 633, 353, 369, 865, 881, 361, 377, 873, 889,
Packit df99a1
 101, 117, 613, 629, 109, 125, 621, 637, 357, 373, 869, 885, 365, 381, 877, 893,
Packit df99a1
 225, 241, 737, 753, 233, 249, 745, 761, 481, 497, 993,1009, 489, 505,1001,1017,
Packit df99a1
 229, 245, 741, 757, 237, 253, 749, 765, 485, 501, 997,1013, 493, 509,1005,1021,
Packit df99a1
  99, 115, 611, 627, 107, 123, 619, 635, 355, 371, 867, 883, 363, 379, 875, 891,
Packit df99a1
 103, 119, 615, 631, 111, 127, 623, 639, 359, 375, 871, 887, 367, 383, 879, 895,
Packit df99a1
 227, 243, 739, 755, 235, 251, 747, 763, 483, 499, 995,1011, 491, 507,1003,1019,
Packit df99a1
 231, 247, 743, 759, 239, 255, 751, 767, 487, 503, 999,1015, 495, 511,1007,1023, // 1023
Packit df99a1
};
Packit df99a1
Packit df99a1
//---------------------------------------------------------------
Packit df99a1
// *** Class IW44Image::Alloc [declaration]
Packit df99a1
Packit df99a1
struct IW44Image::Alloc // DJVU_CLASS
Packit df99a1
{
Packit df99a1
  Alloc *next;
Packit df99a1
  short data[IWALLOCSIZE];
Packit df99a1
  Alloc(Alloc *n);
Packit df99a1
};
Packit df99a1
Packit df99a1
//---------------------------------------------------------------
Packit df99a1
// *** Class IW44Image::Block [implementation]
Packit df99a1
Packit df99a1
Packit df99a1
IW44Image::Block::Block(void)
Packit df99a1
{
Packit df99a1
  pdata[0] = pdata[1] = pdata[2] = pdata[3] = 0;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
IW44Image::Block::zero(int n)
Packit df99a1
{
Packit df99a1
  if (pdata[n>>4])
Packit df99a1
    pdata[n>>4][n&15] = 0;
Packit df99a1
}
Packit df99a1
Packit df99a1
void  
Packit df99a1
IW44Image::Block::read_liftblock(const short *coeff, IW44Image::Map *map)
Packit df99a1
{
Packit df99a1
  int n=0;
Packit df99a1
  for (int n1=0; n1<64; n1++)
Packit df99a1
    {
Packit df99a1
      short *d = data(n1,map);
Packit df99a1
      for (int n2=0; n2<16; n2++,n++)
Packit df99a1
        d[n2] = coeff[zigzagloc[n]];
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
void  
Packit df99a1
IW44Image::Block::write_liftblock(short *coeff, int bmin, int bmax) const
Packit df99a1
{
Packit df99a1
  int n = bmin<<4;
Packit df99a1
  memset(coeff, 0, 1024*sizeof(short));
Packit df99a1
  for (int n1=bmin; n1
Packit df99a1
    {
Packit df99a1
      const short *d = data(n1);
Packit df99a1
      if (d == 0)
Packit df99a1
        n += 16;
Packit df99a1
      else
Packit df99a1
        for (int n2=0; n2<16; n2++,n++)
Packit df99a1
          coeff[zigzagloc[n]] = d[n2];
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
//---------------------------------------------------------------
Packit df99a1
// *** Class IW44Image::Map [implementation]
Packit df99a1
Packit df99a1
Packit df99a1
IW44Image::Map::Map(int w, int h)
Packit df99a1
  :  blocks(0), iw(w), ih(h), chain(0)
Packit df99a1
{
Packit df99a1
  bw = (w+0x20-1) & ~0x1f;
Packit df99a1
  bh = (h+0x20-1) & ~0x1f;
Packit df99a1
  nb = (bw * bh) / (32 * 32);
Packit df99a1
  blocks = new IW44Image::Block[nb];
Packit df99a1
  top = IWALLOCSIZE;
Packit df99a1
}
Packit df99a1
Packit df99a1
IW44Image::Map::~Map()
Packit df99a1
{
Packit df99a1
  while (chain)
Packit df99a1
    {
Packit df99a1
      IW44Image::Alloc *next = chain->next;
Packit df99a1
      delete chain;
Packit df99a1
      chain = next;
Packit df99a1
    }
Packit df99a1
  delete [] blocks;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
IW44Image::Alloc::Alloc(Alloc *n)
Packit df99a1
  : next(n) 
Packit df99a1
{ 
Packit df99a1
  // see note in IW44Image::Map::alloc
Packit df99a1
  memset(data, 0, sizeof(data)); 
Packit df99a1
}
Packit df99a1
Packit df99a1
short *
Packit df99a1
IW44Image::Map::alloc(int n)
Packit df99a1
{
Packit df99a1
  if (top+n > IWALLOCSIZE)
Packit df99a1
    {
Packit df99a1
      // note: everything is cleared long before we use it
Packit df99a1
      // in order to avoid the need for a memory fence.
Packit df99a1
      chain = new IW44Image::Alloc(chain);
Packit df99a1
      top = 0;
Packit df99a1
    }
Packit df99a1
  short *ans = chain->data + top;
Packit df99a1
  top += n;
Packit df99a1
  return ans;
Packit df99a1
}
Packit df99a1
Packit df99a1
short **
Packit df99a1
IW44Image::Map::allocp(int n)
Packit df99a1
{
Packit df99a1
  // Allocate enough room for pointers plus alignment
Packit df99a1
  short *p = alloc( (n+1) * sizeof(short*) / sizeof(short) );
Packit df99a1
  // Align on pointer size
Packit df99a1
  while ( ((size_t)p) & (sizeof(short*)-1) )
Packit df99a1
    p += 1;
Packit df99a1
  // Cast and return
Packit df99a1
  return (short**)p;
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
IW44Image::Map::get_bucket_count(void) const
Packit df99a1
{
Packit df99a1
  int buckets = 0;
Packit df99a1
  for (int blockno=0; blockno
Packit df99a1
    for (int buckno=0; buckno<64; buckno++)
Packit df99a1
      if (blocks[blockno].data(buckno))
Packit df99a1
        buckets += 1;
Packit df99a1
  return buckets;
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned int 
Packit df99a1
IW44Image::Map::get_memory_usage(void) const
Packit df99a1
{
Packit df99a1
  unsigned int usage = sizeof(Map);
Packit df99a1
  usage += sizeof(IW44Image::Block) * nb;
Packit df99a1
  for (IW44Image::Alloc *n = chain; n; n=n->next)
Packit df99a1
    usage += sizeof(IW44Image::Alloc);
Packit df99a1
  return usage;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
void 
Packit df99a1
IW44Image::Map::image(signed char *img8, int rowsize, int pixsep, int fast)
Packit df99a1
{
Packit df99a1
  // Allocate reconstruction buffer
Packit df99a1
  short *data16;
Packit df99a1
  size_t sz = bw * bh;
Packit df99a1
  if (sz / (size_t)bw != (size_t)bh) // multiplication overflow
Packit df99a1
    G_THROW("IW44Image: image size exceeds maximum (corrupted file?)");
Packit df99a1
  GPBuffer<short> gdata16(data16,sz);
Packit df99a1
  // Copy coefficients
Packit df99a1
  int i;
Packit df99a1
  short *p = data16;
Packit df99a1
  const IW44Image::Block *block = blocks;
Packit df99a1
  for (i=0; i
Packit df99a1
    {
Packit df99a1
      for (int j=0; j
Packit df99a1
        {
Packit df99a1
          short liftblock[1024];
Packit df99a1
          // transfer into IW44Image::Block (apply zigzag and scaling)
Packit df99a1
          block->write_liftblock(liftblock);
Packit df99a1
          block++;
Packit df99a1
          // transfer into coefficient matrix at (p+j)
Packit df99a1
          short *pp = p + j;
Packit df99a1
          short *pl = liftblock;
Packit df99a1
          for (int ii=0; ii<32; ii++, pp+=bw,pl+=32)
Packit df99a1
            memcpy((void*)pp, (void*)pl, 32*sizeof(short));
Packit df99a1
        }
Packit df99a1
      // next row of blocks
Packit df99a1
      p += 32*bw;
Packit df99a1
    }
Packit df99a1
  // Reconstruction
Packit df99a1
  if (fast)
Packit df99a1
    {
Packit df99a1
      IW44Image::Transform::Decode::backward(data16, iw, ih, bw, 32, 2);  
Packit df99a1
      p = data16;
Packit df99a1
      for (i=0; i
Packit df99a1
        for (int jj=0; jj
Packit df99a1
          p[bw] = p[bw+1] = p[1] = p[0];
Packit df99a1
    }
Packit df99a1
  else
Packit df99a1
    {
Packit df99a1
      IW44Image::Transform::Decode::backward(data16, iw, ih, bw, 32, 1);  
Packit df99a1
    }
Packit df99a1
  // Copy result into image
Packit df99a1
  p = data16;
Packit df99a1
  signed char *row = img8;  
Packit df99a1
  for (i=0; i
Packit df99a1
    {
Packit df99a1
      signed char *pix = row;
Packit df99a1
      for (int j=0; j
Packit df99a1
        {
Packit df99a1
          int x = (p[j] + iw_round) >> iw_shift;
Packit df99a1
          if (x < -128)
Packit df99a1
            x = -128;
Packit df99a1
          else if (x > 127)
Packit df99a1
            x = 127;
Packit df99a1
          *pix = x;
Packit df99a1
        }
Packit df99a1
      row += rowsize;
Packit df99a1
      p += bw;
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
IW44Image::Map::image(int subsample, const GRect &rect, 
Packit df99a1
              signed char *img8, int rowsize, int pixsep, int fast)
Packit df99a1
{
Packit df99a1
  int i;
Packit df99a1
  // Compute number of decomposition levels
Packit df99a1
  int nlevel = 0;
Packit df99a1
  while (nlevel<5 && (32>>nlevel)>subsample)
Packit df99a1
    nlevel += 1;
Packit df99a1
  int boxsize = 1<
Packit df99a1
  // Parameter check
Packit df99a1
  if (subsample!=(32>>nlevel))
Packit df99a1
    G_THROW( ERR_MSG("IW44Image.sample_factor") );
Packit df99a1
  if (rect.isempty())
Packit df99a1
    G_THROW( ERR_MSG("IW44Image.empty_rect") );    
Packit df99a1
  GRect irect(0,0,(iw+subsample-1)/subsample,(ih+subsample-1)/subsample);
Packit df99a1
  if (rect.xmin<0 || rect.ymin<0 || rect.xmax>irect.xmax || rect.ymax>irect.ymax)
Packit df99a1
    G_THROW( ERR_MSG("IW44Image.bad_rect") );
Packit df99a1
  // Multiresolution rectangles 
Packit df99a1
  // -- needed[i] tells which coeffs are required for the next step
Packit df99a1
  // -- recomp[i] tells which coeffs need to be computed at this level
Packit df99a1
  GRect needed[8];
Packit df99a1
  GRect recomp[8];
Packit df99a1
  int r = 1;
Packit df99a1
  needed[nlevel] = rect;
Packit df99a1
  recomp[nlevel] = rect;
Packit df99a1
  for (i=nlevel-1; i>=0; i--)
Packit df99a1
    {
Packit df99a1
      needed[i] = recomp[i+1];
Packit df99a1
      needed[i].inflate(iw_border*r, iw_border*r);
Packit df99a1
      needed[i].intersect(needed[i], irect);
Packit df99a1
      r += r;
Packit df99a1
      recomp[i].xmin = (needed[i].xmin + r-1) & ~(r-1);
Packit df99a1
      recomp[i].xmax = (needed[i].xmax) & ~(r-1);
Packit df99a1
      recomp[i].ymin = (needed[i].ymin + r-1) & ~(r-1);
Packit df99a1
      recomp[i].ymax = (needed[i].ymax) & ~(r-1);
Packit df99a1
    }
Packit df99a1
  // Working rectangle
Packit df99a1
  // -- a rectangle large enough to hold all the data
Packit df99a1
  GRect work;
Packit df99a1
  work.xmin = (needed[0].xmin) & ~(boxsize-1);
Packit df99a1
  work.ymin = (needed[0].ymin) & ~(boxsize-1);
Packit df99a1
  work.xmax = ((needed[0].xmax-1) & ~(boxsize-1) ) + boxsize;
Packit df99a1
  work.ymax = ((needed[0].ymax-1) & ~(boxsize-1) ) + boxsize;
Packit df99a1
  // -- allocate work buffer
Packit df99a1
  int dataw = work.xmax - work.xmin;     // Note: cannot use inline width() or height()
Packit df99a1
  int datah = work.ymax - work.ymin;     // because Intel C++ compiler optimizes it wrong !
Packit df99a1
  short *data;
Packit df99a1
  GPBuffer<short> gdata(data,dataw*datah);
Packit df99a1
  // Fill working rectangle
Packit df99a1
  // -- loop over liftblocks rows
Packit df99a1
  short *ldata = data;
Packit df99a1
  int blkw = (bw>>5);
Packit df99a1
  const IW44Image::Block *lblock = blocks + (work.ymin>>nlevel)*blkw + (work.xmin>>nlevel);
Packit df99a1
  for (int by=work.ymin; by
Packit df99a1
    {
Packit df99a1
      // -- loop over liftblocks in row
Packit df99a1
      const IW44Image::Block *block = lblock;
Packit df99a1
      short *rdata = ldata;
Packit df99a1
      for (int bx=work.xmin; bx
Packit df99a1
        {
Packit df99a1
          // -- decide how much to load
Packit df99a1
          int mlevel = nlevel;
Packit df99a1
          if (nlevel>2)
Packit df99a1
            if (bx+31<needed[2].xmin || bx>needed[2].xmax ||
Packit df99a1
                by+31<needed[2].ymin || by>needed[2].ymax )
Packit df99a1
              mlevel = 2;
Packit df99a1
          int bmax   = ((1<<(mlevel+mlevel))+15)>>4;
Packit df99a1
          int ppinc  = (1<<(nlevel-mlevel));
Packit df99a1
          int ppmod1 = (dataw<<(nlevel-mlevel));
Packit df99a1
          int ttmod0 = (32 >> mlevel);
Packit df99a1
          int ttmod1 = (ttmod0 << 5);
Packit df99a1
          // -- get current block
Packit df99a1
          short liftblock[1024];
Packit df99a1
          block->write_liftblock(liftblock, 0, bmax );
Packit df99a1
          // -- copy liftblock into image
Packit df99a1
          short *tt = liftblock;
Packit df99a1
          short *pp = rdata;
Packit df99a1
          for (int ii=0; ii
Packit df99a1
            for (int jj=0; jj
Packit df99a1
              pp[jj] = *tt;
Packit df99a1
          // -- next block in row
Packit df99a1
          rdata += boxsize;
Packit df99a1
          block += 1;
Packit df99a1
        }
Packit df99a1
      // -- next row of blocks
Packit df99a1
      ldata += dataw << nlevel;
Packit df99a1
      lblock += blkw;
Packit df99a1
    }
Packit df99a1
  // Perform reconstruction
Packit df99a1
  r = boxsize;
Packit df99a1
  for (i=0; i
Packit df99a1
    {
Packit df99a1
      GRect comp = needed[i];
Packit df99a1
      comp.xmin = comp.xmin & ~(r-1);
Packit df99a1
      comp.ymin = comp.ymin & ~(r-1);
Packit df99a1
      comp.translate(-work.xmin, -work.ymin);
Packit df99a1
      // Fast mode shortcuts finer resolution
Packit df99a1
      if (fast && i>=4) 
Packit df99a1
        {
Packit df99a1
          short *pp = data + comp.ymin*dataw;
Packit df99a1
          for (int ii=comp.ymin; ii
Packit df99a1
            for (int jj=comp.xmin; jj
Packit df99a1
              pp[jj+dataw] = pp[jj+dataw+1] = pp[jj+1] = pp[jj];
Packit df99a1
          break;
Packit df99a1
        }
Packit df99a1
      else
Packit df99a1
        {
Packit df99a1
          short *pp = data + comp.ymin*dataw + comp.xmin;
Packit df99a1
          IW44Image::Transform::Decode::backward(pp, comp.width(), comp.height(), dataw, r, r>>1);
Packit df99a1
        }
Packit df99a1
      r = r>>1;
Packit df99a1
    }
Packit df99a1
  // Copy result into image
Packit df99a1
  GRect nrect = rect;
Packit df99a1
  nrect.translate(-work.xmin, -work.ymin);
Packit df99a1
  short *p = data + nrect.ymin*dataw;
Packit df99a1
  signed char *row = img8;  
Packit df99a1
  for (i=nrect.ymin; i
Packit df99a1
    {
Packit df99a1
      int j;
Packit df99a1
      signed char *pix = row;
Packit df99a1
      for (j=nrect.xmin; j
Packit df99a1
        {
Packit df99a1
          int x = (p[j] + iw_round) >> iw_shift;
Packit df99a1
          if (x < -128)
Packit df99a1
            x = -128;
Packit df99a1
          else if (x > 127)
Packit df99a1
            x = 127;
Packit df99a1
          *pix = x;
Packit df99a1
        }
Packit df99a1
      row += rowsize;
Packit df99a1
      p += dataw;
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
// ENCODING/DECODING WAVELET COEFFICIENTS 
Packit df99a1
//    USING HIERARCHICAL SET DIFFERENCE
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
Packit df99a1
Packit df99a1
//-----------------------------------------------
Packit df99a1
// Class IW44Image::Codec [implementation]
Packit df99a1
// Maintains information shared while encoding or decoding
Packit df99a1
Packit df99a1
Packit df99a1
// Constant
Packit df99a1
Packit df99a1
static const struct { int start; int size; }  
Packit df99a1
bandbuckets[] = 
Packit df99a1
{
Packit df99a1
  // Code first bucket and number of buckets in each band
Packit df99a1
  { 0, 1 }, // -- band zero contains all lores info
Packit df99a1
  { 1, 1 }, { 2, 1 }, { 3, 1 }, 
Packit df99a1
  { 4, 4 }, { 8, 4 }, { 12,4 }, 
Packit df99a1
  { 16,16 }, { 32,16 }, { 48,16 }, 
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
// IW44Image::Codec constructor
Packit df99a1
Packit df99a1
IW44Image::Codec::Codec(IW44Image::Map &xmap)
Packit df99a1
  : map(xmap), 
Packit df99a1
    curband(0),
Packit df99a1
    curbit(1)
Packit df99a1
{
Packit df99a1
  // Initialize quantification
Packit df99a1
  int  j;
Packit df99a1
  int  i = 0;
Packit df99a1
  const int *q = iw_quant;
Packit df99a1
  // -- lo coefficients
Packit df99a1
  for (j=0; i<4; j++)
Packit df99a1
    quant_lo[i++] = *q++;
Packit df99a1
  for (j=0; j<4; j++)
Packit df99a1
    quant_lo[i++] = *q;
Packit df99a1
  q += 1;
Packit df99a1
  for (j=0; j<4; j++)
Packit df99a1
    quant_lo[i++] = *q;
Packit df99a1
  q += 1;
Packit df99a1
  for (j=0; j<4; j++)
Packit df99a1
    quant_lo[i++] = *q;
Packit df99a1
  q += 1;
Packit df99a1
  // -- hi coefficients
Packit df99a1
  quant_hi[0] = 0;
Packit df99a1
  for (j=1; j<10; j++)
Packit df99a1
    quant_hi[j] = *q++;
Packit df99a1
  // Initialize coding contexts
Packit df99a1
  memset((void*)ctxStart, 0, sizeof(ctxStart));
Packit df99a1
  memset((void*)ctxBucket, 0, sizeof(ctxBucket));
Packit df99a1
  ctxMant = 0;
Packit df99a1
  ctxRoot = 0;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
// IW44Image::Codec destructor
Packit df99a1
Packit df99a1
IW44Image::Codec::~Codec() {}
Packit df99a1
Packit df99a1
// is_null_slice
Packit df99a1
// -- check if data can be produced for this band/mask
Packit df99a1
// -- also fills the sure_zero array
Packit df99a1
Packit df99a1
int 
Packit df99a1
IW44Image::Codec::is_null_slice(int bit, int band)
Packit df99a1
{
Packit df99a1
  if (band == 0)
Packit df99a1
    {
Packit df99a1
      int is_null = 1;
Packit df99a1
      for (int i=0; i<16; i++) 
Packit df99a1
        {
Packit df99a1
          int threshold = quant_lo[i];
Packit df99a1
          coeffstate[i] = ZERO;
Packit df99a1
          if (threshold>0 && threshold<0x8000)
Packit df99a1
            {
Packit df99a1
              coeffstate[i] = UNK;
Packit df99a1
              is_null = 0;
Packit df99a1
            }
Packit df99a1
        }
Packit df99a1
      return is_null;
Packit df99a1
    }
Packit df99a1
  else
Packit df99a1
    {
Packit df99a1
      int threshold = quant_hi[band];
Packit df99a1
      return (! (threshold>0 && threshold<0x8000));
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
// code_slice
Packit df99a1
// -- read/write a slice of datafile
Packit df99a1
Packit df99a1
int
Packit df99a1
IW44Image::Codec::Decode::code_slice(ZPCodec &zp)
Packit df99a1
{
Packit df99a1
  // Check that code_slice can still run
Packit df99a1
  if (curbit < 0)
Packit df99a1
    return 0;
Packit df99a1
  // Perform coding
Packit df99a1
  if (! is_null_slice(curbit, curband))
Packit df99a1
    {
Packit df99a1
      for (int blockno=0; blockno
Packit df99a1
        {
Packit df99a1
          int fbucket = bandbuckets[curband].start;
Packit df99a1
          int nbucket = bandbuckets[curband].size;
Packit df99a1
          decode_buckets(zp, curbit, curband, 
Packit df99a1
                           map.blocks[blockno], 
Packit df99a1
                           fbucket, nbucket);
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  return finish_code_slice(zp);
Packit df99a1
}
Packit df99a1
Packit df99a1
// code_slice
Packit df99a1
// -- read/write a slice of datafile
Packit df99a1
Packit df99a1
int
Packit df99a1
IW44Image::Codec::finish_code_slice(ZPCodec &zp)
Packit df99a1
{
Packit df99a1
  // Reduce quantization threshold
Packit df99a1
  quant_hi[curband] = quant_hi[curband] >> 1;
Packit df99a1
  if (curband == 0)
Packit df99a1
    for (int i=0; i<16; i++) 
Packit df99a1
      quant_lo[i] = quant_lo[i] >> 1;
Packit df99a1
  // Proceed to the next slice
Packit df99a1
  if (++curband >= (int)(sizeof(bandbuckets)/sizeof(bandbuckets[0])))
Packit df99a1
    {
Packit df99a1
      curband = 0;
Packit df99a1
      curbit += 1;
Packit df99a1
      if (quant_hi[(sizeof(bandbuckets)/sizeof(bandbuckets[0]))-1] == 0)
Packit df99a1
        {
Packit df99a1
          // All quantization thresholds are null
Packit df99a1
          curbit = -1;
Packit df99a1
          return 0;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  return 1;
Packit df99a1
}
Packit df99a1
Packit df99a1
// decode_prepare
Packit df99a1
// -- prepare the states before decoding buckets
Packit df99a1
Packit df99a1
int
Packit df99a1
IW44Image::Codec::decode_prepare(int fbucket, int nbucket, IW44Image::Block &blk)
Packit df99a1
{  
Packit df99a1
  int bbstate = 0;
Packit df99a1
  char *cstate = coeffstate;
Packit df99a1
  if (fbucket)
Packit df99a1
    {
Packit df99a1
      // Band other than zero
Packit df99a1
      for (int buckno=0; buckno
Packit df99a1
        {
Packit df99a1
          int bstatetmp = 0;
Packit df99a1
          const short *pcoeff = blk.data(fbucket+buckno);
Packit df99a1
          if (! pcoeff)
Packit df99a1
            {
Packit df99a1
              // cstate[0..15] will be filled later
Packit df99a1
              bstatetmp = UNK;
Packit df99a1
            }
Packit df99a1
          else
Packit df99a1
            {
Packit df99a1
              for (int i=0; i<16; i++)
Packit df99a1
                {
Packit df99a1
                  int cstatetmp = UNK;
Packit df99a1
                  if (pcoeff[i])
Packit df99a1
                    cstatetmp = ACTIVE;
Packit df99a1
                  cstate[i] = cstatetmp;
Packit df99a1
                  bstatetmp |= cstatetmp;
Packit df99a1
                }
Packit df99a1
            }
Packit df99a1
          bucketstate[buckno] = bstatetmp;
Packit df99a1
          bbstate |= bstatetmp;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  else
Packit df99a1
    {
Packit df99a1
      // Band zero ( fbucket==0 implies band==zero and nbucket==1 )
Packit df99a1
      const short *pcoeff = blk.data(0);
Packit df99a1
      if (! pcoeff)
Packit df99a1
        {
Packit df99a1
          // cstate[0..15] will be filled later
Packit df99a1
          bbstate = UNK;      
Packit df99a1
        }
Packit df99a1
      else
Packit df99a1
        {
Packit df99a1
          for (int i=0; i<16; i++)
Packit df99a1
            {
Packit df99a1
              int cstatetmp = cstate[i];
Packit df99a1
              if (cstatetmp != ZERO)
Packit df99a1
                {
Packit df99a1
                  cstatetmp = UNK;
Packit df99a1
                  if (pcoeff[i])
Packit df99a1
                    cstatetmp = ACTIVE;
Packit df99a1
                }
Packit df99a1
              cstate[i] = cstatetmp;
Packit df99a1
              bbstate |= cstatetmp;
Packit df99a1
            }
Packit df99a1
        }
Packit df99a1
      bucketstate[0] = bbstate;
Packit df99a1
    }
Packit df99a1
  return bbstate;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
// decode_buckets
Packit df99a1
// -- code a sequence of buckets in a given block
Packit df99a1
Packit df99a1
void
Packit df99a1
IW44Image::Codec::decode_buckets(ZPCodec &zp, int bit, int band, 
Packit df99a1
                         IW44Image::Block &blk,
Packit df99a1
                         int fbucket, int nbucket)
Packit df99a1
{
Packit df99a1
  // compute state of all coefficients in all buckets
Packit df99a1
  int bbstate = decode_prepare(fbucket, nbucket, blk);
Packit df99a1
  // code root bit
Packit df99a1
  if ((nbucket<16) || (bbstate&ACTIVE))
Packit df99a1
    {
Packit df99a1
      bbstate |= NEW;
Packit df99a1
    }
Packit df99a1
  else if (bbstate & UNK)
Packit df99a1
    {
Packit df99a1
      if (zp.decoder(ctxRoot))
Packit df99a1
        bbstate |= NEW;
Packit df99a1
#ifdef TRACE
Packit df99a1
      DjVuPrintMessage("bbstate[bit=%d,band=%d] = %d\n", bit, band, bbstate);
Packit df99a1
#endif
Packit df99a1
    }
Packit df99a1
  
Packit df99a1
  // code bucket bits
Packit df99a1
  if (bbstate & NEW)
Packit df99a1
    for (int buckno=0; buckno
Packit df99a1
      {
Packit df99a1
        // Code bucket bit
Packit df99a1
        if (bucketstate[buckno] & UNK)
Packit df99a1
          {
Packit df99a1
            // Context
Packit df99a1
            int ctx = 0;
Packit df99a1
#ifndef NOCTX_BUCKET_UPPER
Packit df99a1
            if (band>0)
Packit df99a1
              {
Packit df99a1
                int k = (fbucket+buckno)<<2;
Packit df99a1
                const short *b = blk.data(k>>4);
Packit df99a1
                if (b)
Packit df99a1
                  {
Packit df99a1
                    k = k & 0xf;
Packit df99a1
                    if (b[k])
Packit df99a1
                      ctx += 1;
Packit df99a1
                    if (b[k+1])
Packit df99a1
                      ctx += 1;
Packit df99a1
                    if (b[k+2])
Packit df99a1
                      ctx += 1;
Packit df99a1
                    if (ctx<3 && b[k+3])
Packit df99a1
                      ctx += 1;
Packit df99a1
                  }
Packit df99a1
              }
Packit df99a1
#endif // NOCTX_BUCKET_UPPER
Packit df99a1
#ifndef NOCTX_BUCKET_ACTIVE
Packit df99a1
            if (bbstate & ACTIVE)
Packit df99a1
              ctx |= 4; 
Packit df99a1
#endif
Packit df99a1
            // Code
Packit df99a1
            if (zp.decoder( ctxBucket[band][ctx] ))
Packit df99a1
              bucketstate[buckno] |= NEW;
Packit df99a1
#ifdef TRACE
Packit df99a1
            DjVuPrintMessage("  bucketstate[bit=%d,band=%d,buck=%d] = %d\n", 
Packit df99a1
                   bit, band, buckno, bucketstate[buckno]);
Packit df99a1
#endif
Packit df99a1
          }
Packit df99a1
      }
Packit df99a1
Packit df99a1
  // code new active coefficient (with their sign)
Packit df99a1
  if (bbstate & NEW)
Packit df99a1
    {
Packit df99a1
      int thres = quant_hi[band];
Packit df99a1
      char *cstate = coeffstate;
Packit df99a1
      for (int buckno=0; buckno
Packit df99a1
        if (bucketstate[buckno] & NEW)
Packit df99a1
          {
Packit df99a1
            int i;
Packit df99a1
            short *pcoeff = (short*)blk.data(fbucket+buckno);
Packit df99a1
            if (!pcoeff)
Packit df99a1
              {
Packit df99a1
                pcoeff = blk.data(fbucket+buckno, &map);
Packit df99a1
                // time to fill cstate[0..15]
Packit df99a1
                if (fbucket == 0) // band zero
Packit df99a1
                  {
Packit df99a1
                    for (i=0; i<16; i++)
Packit df99a1
                      if (cstate[i] != ZERO)
Packit df99a1
                        cstate[i] = UNK;
Packit df99a1
                  }
Packit df99a1
                else
Packit df99a1
                  {
Packit df99a1
                    for (i=0; i<16; i++)
Packit df99a1
                      cstate[i] = UNK;
Packit df99a1
                  }
Packit df99a1
              }
Packit df99a1
#ifndef NOCTX_EXPECT
Packit df99a1
            int gotcha = 0;
Packit df99a1
            const int maxgotcha = 7;
Packit df99a1
            for (i=0; i<16; i++)
Packit df99a1
              if (cstate[i] & UNK)
Packit df99a1
                gotcha += 1;
Packit df99a1
#endif
Packit df99a1
            for (i=0; i<16; i++)
Packit df99a1
              {
Packit df99a1
                if (cstate[i] & UNK)
Packit df99a1
                  {
Packit df99a1
                    // find lores threshold
Packit df99a1
                    if (band == 0)
Packit df99a1
                      thres = quant_lo[i];
Packit df99a1
                    // prepare context
Packit df99a1
                    int ctx = 0;
Packit df99a1
#ifndef NOCTX_EXPECT
Packit df99a1
                    if (gotcha>=maxgotcha)
Packit df99a1
                      ctx = maxgotcha;
Packit df99a1
                    else
Packit df99a1
                      ctx = gotcha;
Packit df99a1
#endif
Packit df99a1
#ifndef NOCTX_ACTIVE
Packit df99a1
                    if (bucketstate[buckno] & ACTIVE)
Packit df99a1
                      ctx |= 8;
Packit df99a1
#endif
Packit df99a1
                    // code difference bit
Packit df99a1
                    if (zp.decoder( ctxStart[ctx] ))
Packit df99a1
                      {
Packit df99a1
                        cstate[i] |= NEW;
Packit df99a1
                        int halfthres = thres>>1;
Packit df99a1
                        int coeff = thres+halfthres-(halfthres>>2);
Packit df99a1
                        if (zp.IWdecoder())
Packit df99a1
                          pcoeff[i] = -coeff;
Packit df99a1
                        else
Packit df99a1
                          pcoeff[i] = coeff;
Packit df99a1
                      }
Packit df99a1
#ifndef NOCTX_EXPECT
Packit df99a1
                    if (cstate[i] & NEW)
Packit df99a1
                      gotcha = 0;
Packit df99a1
                    else if (gotcha > 0)
Packit df99a1
                      gotcha -= 1;
Packit df99a1
#endif
Packit df99a1
#ifdef TRACE
Packit df99a1
                    DjVuPrintMessage("    coeffstate[bit=%d,band=%d,buck=%d,c=%d] = %d\n", 
Packit df99a1
                           bit, band, buckno, i, cstate[i]);
Packit df99a1
#endif
Packit df99a1
                  }
Packit df99a1
              }
Packit df99a1
          }
Packit df99a1
    }
Packit df99a1
  
Packit df99a1
  // code mantissa bits
Packit df99a1
  if (bbstate & ACTIVE)
Packit df99a1
    {
Packit df99a1
      int thres = quant_hi[band];
Packit df99a1
      char *cstate = coeffstate;
Packit df99a1
      for (int buckno=0; buckno
Packit df99a1
        if (bucketstate[buckno] & ACTIVE)
Packit df99a1
          {
Packit df99a1
            short *pcoeff = (short*)blk.data(fbucket+buckno);
Packit df99a1
            for (int i=0; i<16; i++)
Packit df99a1
              if (cstate[i] & ACTIVE)
Packit df99a1
                {
Packit df99a1
                  int coeff = pcoeff[i];
Packit df99a1
                  if (coeff < 0)
Packit df99a1
                    coeff = -coeff;
Packit df99a1
                  // find lores threshold
Packit df99a1
                  if (band == 0)
Packit df99a1
                    thres = quant_lo[i];
Packit df99a1
                  // adjust coefficient
Packit df99a1
                  if (coeff <= 3*thres)
Packit df99a1
                    {
Packit df99a1
                      // second mantissa bit
Packit df99a1
                      coeff = coeff + (thres>>2);
Packit df99a1
                      if (zp.decoder(ctxMant))
Packit df99a1
                        coeff = coeff + (thres>>1);
Packit df99a1
                      else
Packit df99a1
                        coeff = coeff - thres + (thres>>1);
Packit df99a1
                    }
Packit df99a1
                  else
Packit df99a1
                    {
Packit df99a1
                      if (zp.IWdecoder())
Packit df99a1
                        coeff = coeff + (thres>>1);
Packit df99a1
                      else
Packit df99a1
                        coeff = coeff - thres + (thres>>1);
Packit df99a1
                    }
Packit df99a1
                  // store coefficient
Packit df99a1
                  if (pcoeff[i] > 0)
Packit df99a1
                    pcoeff[i] = coeff;
Packit df99a1
                  else
Packit df99a1
                    pcoeff[i] = -coeff;
Packit df99a1
                }
Packit df99a1
          }
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
// UTILITIES
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
Packit df99a1
Packit df99a1
#ifdef min
Packit df99a1
#undef min
Packit df99a1
#endif
Packit df99a1
static inline int
Packit df99a1
min(const int x, const int y)
Packit df99a1
{
Packit df99a1
  return (x <= y) ? x : y;
Packit df99a1
}
Packit df99a1
Packit df99a1
#ifdef max
Packit df99a1
#undef max
Packit df99a1
#endif
Packit df99a1
static inline int
Packit df99a1
max(const int x, const int y)
Packit df99a1
{
Packit df99a1
  return (y <= x) ? x : y;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
void 
Packit df99a1
IW44Image::PrimaryHeader::decode(GP<ByteStream> gbs)
Packit df99a1
{
Packit df99a1
  serial = gbs->read8();
Packit df99a1
  slices = gbs->read8();
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
IW44Image::SecondaryHeader::decode(GP<ByteStream> gbs)
Packit df99a1
{
Packit df99a1
  major = gbs->read8();
Packit df99a1
  minor = gbs->read8();
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
IW44Image::TertiaryHeader::decode(GP<ByteStream> gbs, int major, int minor)
Packit df99a1
{
Packit df99a1
  xhi = gbs->read8();
Packit df99a1
  xlo = gbs->read8();
Packit df99a1
  yhi = gbs->read8();
Packit df99a1
  ylo = gbs->read8();
Packit df99a1
  crcbdelay = 0;
Packit df99a1
  if (major== 1 && minor>=2)
Packit df99a1
    crcbdelay = gbs->read8();
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
// CLASS IW44Image
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
Packit df99a1
IW44Image::IW44Image(void)
Packit df99a1
  : db_frac(1.0),
Packit df99a1
    ymap(0), cbmap(0), crmap(0),
Packit df99a1
    cslice(0), cserial(0), cbytes(0)
Packit df99a1
{}
Packit df99a1
Packit df99a1
IW44Image::~IW44Image()
Packit df99a1
{
Packit df99a1
  delete ymap;
Packit df99a1
  delete cbmap;
Packit df99a1
  delete crmap;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<IW44Image>
Packit df99a1
IW44Image::create_decode(const ImageType itype)
Packit df99a1
{
Packit df99a1
  switch(itype)
Packit df99a1
  {
Packit df99a1
  case COLOR:
Packit df99a1
    return new IWPixmap();
Packit df99a1
  case GRAY:
Packit df99a1
    return new IWBitmap();
Packit df99a1
  default:
Packit df99a1
    return 0;
Packit df99a1
  }
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
IW44Image::encode_chunk(GP<ByteStream>, const IWEncoderParms &)
Packit df99a1
{
Packit df99a1
  G_THROW( ERR_MSG("IW44Image.codec_open2") );
Packit df99a1
  return 0;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
IW44Image::encode_iff(IFFByteStream &, int nchunks, const IWEncoderParms *)
Packit df99a1
{
Packit df99a1
  G_THROW( ERR_MSG("IW44Image.codec_open2") );
Packit df99a1
}
Packit df99a1
Packit df99a1
  
Packit df99a1
void 
Packit df99a1
IWBitmap::close_codec(void)
Packit df99a1
{
Packit df99a1
  delete ycodec;
Packit df99a1
  ycodec = 0;
Packit df99a1
  cslice = cbytes = cserial = 0;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
IWPixmap::close_codec(void)
Packit df99a1
{
Packit df99a1
  delete ycodec;
Packit df99a1
  delete cbcodec;
Packit df99a1
  delete crcodec;
Packit df99a1
  ycodec = crcodec = cbcodec = 0;
Packit df99a1
  cslice = cbytes = cserial = 0;
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
IW44Image::get_width(void) const
Packit df99a1
{
Packit df99a1
  return (ymap)?(ymap->iw):0;
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
IW44Image::get_height(void) const
Packit df99a1
{
Packit df99a1
  return (ymap)?(ymap->ih):0;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
// CLASS IWBITMAP
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
Packit df99a1
IWBitmap::IWBitmap(void )
Packit df99a1
: IW44Image(), ycodec(0)
Packit df99a1
{}
Packit df99a1
Packit df99a1
IWBitmap::~IWBitmap()
Packit df99a1
{
Packit df99a1
  close_codec();
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
IWBitmap::get_percent_memory(void) const
Packit df99a1
{
Packit df99a1
  int buckets = 0;
Packit df99a1
  int maximum = 0;
Packit df99a1
  if (ymap) 
Packit df99a1
    {
Packit df99a1
      buckets += ymap->get_bucket_count();
Packit df99a1
      maximum += 64 * ymap->nb;
Packit df99a1
    }
Packit df99a1
  return 100*buckets/ (maximum ? maximum : 1);
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned int
Packit df99a1
IWBitmap::get_memory_usage(void) const
Packit df99a1
{
Packit df99a1
  unsigned int usage = sizeof(GBitmap);
Packit df99a1
  if (ymap)
Packit df99a1
    usage += ymap->get_memory_usage();
Packit df99a1
  return usage;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
GP<GBitmap> 
Packit df99a1
IWBitmap::get_bitmap(void)
Packit df99a1
{
Packit df99a1
  // Check presence of data
Packit df99a1
  if (ymap == 0)
Packit df99a1
    return 0;
Packit df99a1
  // Perform wavelet reconstruction
Packit df99a1
  int w = ymap->iw;
Packit df99a1
  int h = ymap->ih;
Packit df99a1
  GP<GBitmap> pbm = GBitmap::create(h, w);
Packit df99a1
  ymap->image((signed char*)(*pbm)[0],pbm->rowsize());
Packit df99a1
  // Shift image data
Packit df99a1
  for (int i=0; i
Packit df99a1
    {
Packit df99a1
      unsigned char *urow = (*pbm)[i];
Packit df99a1
      signed char *srow = (signed char*)urow;
Packit df99a1
      for (int j=0; j
Packit df99a1
        urow[j] = (int)(srow[j]) + 128;
Packit df99a1
    }
Packit df99a1
  pbm->set_grays(256);
Packit df99a1
  return pbm;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
GP<GBitmap>
Packit df99a1
IWBitmap::get_bitmap(int subsample, const GRect &rect)
Packit df99a1
{
Packit df99a1
  if (ymap == 0)
Packit df99a1
    return 0;
Packit df99a1
  // Allocate bitmap
Packit df99a1
  int w = rect.width();
Packit df99a1
  int h = rect.height();
Packit df99a1
  GP<GBitmap> pbm = GBitmap::create(h,w);
Packit df99a1
  ymap->image(subsample, rect, (signed char*)(*pbm)[0],pbm->rowsize());
Packit df99a1
  // Shift image data
Packit df99a1
  for (int i=0; i
Packit df99a1
    {
Packit df99a1
      unsigned char *urow = (*pbm)[i];
Packit df99a1
      signed char *srow = (signed char*)urow;
Packit df99a1
      for (int j=0; j
Packit df99a1
        urow[j] = (int)(srow[j]) + 128;
Packit df99a1
    }
Packit df99a1
  pbm->set_grays(256);
Packit df99a1
  return pbm;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
int
Packit df99a1
IWBitmap::decode_chunk(GP<ByteStream> gbs)
Packit df99a1
{
Packit df99a1
  // Open
Packit df99a1
  if (! ycodec)
Packit df99a1
  {
Packit df99a1
    cslice = cserial = 0;
Packit df99a1
    delete ymap;
Packit df99a1
    ymap = 0;
Packit df99a1
  }
Packit df99a1
  // Read primary header
Packit df99a1
  struct IW44Image::PrimaryHeader primary;
Packit df99a1
  primary.decode(gbs);
Packit df99a1
  if (primary.serial != cserial)
Packit df99a1
    G_THROW( ERR_MSG("IW44Image.wrong_serial") );
Packit df99a1
  int nslices = cslice + primary.slices;
Packit df99a1
  // Read auxilliary headers
Packit df99a1
  if (cserial == 0)
Packit df99a1
    {
Packit df99a1
      struct IW44Image::SecondaryHeader secondary;
Packit df99a1
      secondary.decode(gbs);
Packit df99a1
      if ((secondary.major & 0x7f) != IWCODEC_MAJOR)
Packit df99a1
        G_THROW( ERR_MSG("IW44Image.incompat_codec") );
Packit df99a1
      if (secondary.minor > IWCODEC_MINOR)
Packit df99a1
        G_THROW( ERR_MSG("IW44Image.recent_codec") );
Packit df99a1
      // Read tertiary header
Packit df99a1
      struct IW44Image::TertiaryHeader tertiary;
Packit df99a1
      tertiary.decode(gbs, secondary.major & 0x7f, secondary.minor);
Packit df99a1
      if (! (secondary.major & 0x80))
Packit df99a1
        G_THROW( ERR_MSG("IW44Image.has_color") );
Packit df99a1
      // Create ymap and ycodec
Packit df99a1
      int w = (tertiary.xhi << 8) | tertiary.xlo;
Packit df99a1
      int h = (tertiary.yhi << 8) | tertiary.ylo;
Packit df99a1
      assert(! ymap);
Packit df99a1
      ymap = new Map(w, h);
Packit df99a1
      assert(! ycodec);
Packit df99a1
      ycodec = new Codec::Decode(*ymap);
Packit df99a1
    }
Packit df99a1
  // Read data
Packit df99a1
  assert(ymap);
Packit df99a1
  assert(ycodec);
Packit df99a1
  GP<ZPCodec> gzp=ZPCodec::create(gbs, false, true);
Packit df99a1
  ZPCodec &zp=*gzp;
Packit df99a1
  int flag = 1;
Packit df99a1
  while (flag && cslice
Packit df99a1
    {
Packit df99a1
      flag = ycodec->code_slice(zp);
Packit df99a1
      cslice++;
Packit df99a1
    }
Packit df99a1
  // Return
Packit df99a1
  cserial += 1;
Packit df99a1
  return nslices;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
IWBitmap::parm_dbfrac(float frac)
Packit df99a1
{
Packit df99a1
  if (frac>0 && frac<=1)
Packit df99a1
    db_frac = frac;
Packit df99a1
  else
Packit df99a1
    G_THROW( ERR_MSG("IW44Image.param_range") );
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
int 
Packit df99a1
IWBitmap::get_serial(void)
Packit df99a1
{
Packit df99a1
  return cserial;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
IWBitmap::decode_iff(IFFByteStream &iff, int maxchunks)
Packit df99a1
{
Packit df99a1
  if (ycodec)
Packit df99a1
    G_THROW( ERR_MSG("IW44Image.left_open2") );
Packit df99a1
  GUTF8String chkid;
Packit df99a1
  iff.get_chunk(chkid);
Packit df99a1
  if (chkid != "FORM:BM44")
Packit df99a1
    G_THROW( ERR_MSG("IW44Image.corrupt_BM44") );
Packit df99a1
  while (--maxchunks>=0 && iff.get_chunk(chkid))
Packit df99a1
    {
Packit df99a1
      if (chkid == "BM44")
Packit df99a1
        decode_chunk(iff.get_bytestream());
Packit df99a1
      iff.close_chunk();
Packit df99a1
    }
Packit df99a1
  iff.close_chunk();
Packit df99a1
  close_codec();
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
// CLASS IWENCODERPARMS
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
Packit df99a1
Packit df99a1
IWEncoderParms::IWEncoderParms(void)
Packit df99a1
{
Packit df99a1
  // Zero represent default values
Packit df99a1
  memset((void*)this, 0, sizeof(IWEncoderParms));
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
// CLASS IWPIXMAP
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
Packit df99a1
Packit df99a1
IWPixmap::IWPixmap(void)
Packit df99a1
: IW44Image(), crcb_delay(10), crcb_half(0), ycodec(0), cbcodec(0), crcodec(0)
Packit df99a1
{}
Packit df99a1
Packit df99a1
IWPixmap::~IWPixmap()
Packit df99a1
{
Packit df99a1
  close_codec();
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
IWPixmap::get_percent_memory(void) const
Packit df99a1
{
Packit df99a1
  int buckets = 0;
Packit df99a1
  int maximum = 0;
Packit df99a1
  if (ymap)
Packit df99a1
    {
Packit df99a1
      buckets += ymap->get_bucket_count();
Packit df99a1
      maximum += 64*ymap->nb;
Packit df99a1
    }
Packit df99a1
  if (cbmap)
Packit df99a1
    {
Packit df99a1
      buckets += cbmap->get_bucket_count();
Packit df99a1
      maximum += 64*cbmap->nb;
Packit df99a1
    }
Packit df99a1
  if (crmap)
Packit df99a1
    {
Packit df99a1
      buckets += crmap->get_bucket_count();
Packit df99a1
      maximum += 64*crmap->nb;
Packit df99a1
    }
Packit df99a1
  return 100*buckets/ (maximum ? maximum : 1);
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned int
Packit df99a1
IWPixmap::get_memory_usage(void) const
Packit df99a1
{
Packit df99a1
  unsigned int usage = sizeof(GPixmap);
Packit df99a1
  if (ymap)
Packit df99a1
    usage += ymap->get_memory_usage();
Packit df99a1
  if (cbmap)
Packit df99a1
    usage += cbmap->get_memory_usage();
Packit df99a1
  if (crmap)
Packit df99a1
    usage += crmap->get_memory_usage();
Packit df99a1
  return usage;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
GP<GPixmap> 
Packit df99a1
IWPixmap::get_pixmap(void)
Packit df99a1
{
Packit df99a1
  // Check presence of data
Packit df99a1
  if (ymap == 0)
Packit df99a1
    return 0;
Packit df99a1
  // Allocate pixmap
Packit df99a1
  int w = ymap->iw;
Packit df99a1
  int h = ymap->ih;
Packit df99a1
  GP<GPixmap> ppm = GPixmap::create(h, w);
Packit df99a1
  // Perform wavelet reconstruction
Packit df99a1
  signed char *ptr = (signed char*) (*ppm)[0];
Packit df99a1
  int rowsep = ppm->rowsize() * sizeof(GPixel);
Packit df99a1
  int pixsep = sizeof(GPixel);
Packit df99a1
  ymap->image(ptr, rowsep, pixsep);
Packit df99a1
  if (crmap && cbmap && crcb_delay >= 0)
Packit df99a1
  {
Packit df99a1
    cbmap->image(ptr+1, rowsep, pixsep, crcb_half);
Packit df99a1
    crmap->image(ptr+2, rowsep, pixsep, crcb_half);
Packit df99a1
  }
Packit df99a1
  // Convert image data to RGB
Packit df99a1
  if (crmap && cbmap && crcb_delay >= 0)
Packit df99a1
    {
Packit df99a1
      Transform::Decode::YCbCr_to_RGB((*ppm)[0], w, h, ppm->rowsize());
Packit df99a1
    }
Packit df99a1
  else
Packit df99a1
    {
Packit df99a1
      for (int i=0; i
Packit df99a1
        {
Packit df99a1
          GPixel *pixrow = (*ppm)[i];
Packit df99a1
          for (int j=0; j
Packit df99a1
            pixrow->b = pixrow->g = pixrow->r 
Packit df99a1
              = 127 - (int)(((signed char*)pixrow)[0]);
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  // Return
Packit df99a1
  return ppm;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
GP<GPixmap>
Packit df99a1
IWPixmap::get_pixmap(int subsample, const GRect &rect)
Packit df99a1
{
Packit df99a1
  if (ymap == 0)
Packit df99a1
    return 0;
Packit df99a1
  // Allocate
Packit df99a1
  int w = rect.width();
Packit df99a1
  int h = rect.height();
Packit df99a1
  GP<GPixmap> ppm = GPixmap::create(h,w);
Packit df99a1
  // Perform wavelet reconstruction
Packit df99a1
  signed char *ptr = (signed char*) (*ppm)[0];
Packit df99a1
  int rowsep = ppm->rowsize() * sizeof(GPixel);
Packit df99a1
  int pixsep = sizeof(GPixel);
Packit df99a1
  ymap->image(subsample, rect, ptr, rowsep, pixsep);
Packit df99a1
  if (crmap && cbmap && crcb_delay >= 0)
Packit df99a1
  {
Packit df99a1
    cbmap->image(subsample, rect, ptr+1, rowsep, pixsep, crcb_half);
Packit df99a1
    crmap->image(subsample, rect, ptr+2, rowsep, pixsep, crcb_half);
Packit df99a1
  }
Packit df99a1
  // Convert image data to RGB
Packit df99a1
  if (crmap && cbmap && crcb_delay >= 0)
Packit df99a1
    {
Packit df99a1
      Transform::Decode::YCbCr_to_RGB((*ppm)[0], w, h, ppm->rowsize());
Packit df99a1
    }
Packit df99a1
  else
Packit df99a1
    {
Packit df99a1
      for (int i=0; i
Packit df99a1
        {
Packit df99a1
          GPixel *pixrow = (*ppm)[i];
Packit df99a1
          for (int j=0; j
Packit df99a1
            pixrow->b = pixrow->g = pixrow->r 
Packit df99a1
              = 127 - (int)(((signed char*)pixrow)[0]);
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  // Return
Packit df99a1
  return ppm;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
int
Packit df99a1
IWPixmap::decode_chunk(GP<ByteStream> gbs)
Packit df99a1
{
Packit df99a1
  // Open
Packit df99a1
  if (! ycodec)
Packit df99a1
  {
Packit df99a1
      cslice = cserial = 0;
Packit df99a1
      delete ymap;
Packit df99a1
      ymap = 0;
Packit df99a1
  }
Packit df99a1
Packit df99a1
  // Read primary header
Packit df99a1
  struct IW44Image::PrimaryHeader primary;
Packit df99a1
  primary.decode(gbs);
Packit df99a1
  if (primary.serial != cserial)
Packit df99a1
    G_THROW( ERR_MSG("IW44Image.wrong_serial2") );
Packit df99a1
  int nslices = cslice + primary.slices;
Packit df99a1
  // Read secondary header
Packit df99a1
  if (cserial == 0)
Packit df99a1
    {
Packit df99a1
      struct IW44Image::SecondaryHeader secondary;
Packit df99a1
      secondary.decode(gbs);
Packit df99a1
      if ((secondary.major & 0x7f) != IWCODEC_MAJOR)
Packit df99a1
        G_THROW( ERR_MSG("IW44Image.incompat_codec2") );
Packit df99a1
      if (secondary.minor > IWCODEC_MINOR)
Packit df99a1
        G_THROW( ERR_MSG("IW44Image.recent_codec2") );
Packit df99a1
      // Read tertiary header
Packit df99a1
      struct IW44Image::TertiaryHeader tertiary;
Packit df99a1
      tertiary.decode(gbs, secondary.major & 0x7f, secondary.minor);
Packit df99a1
      // Handle header information
Packit df99a1
      int w = (tertiary.xhi << 8) | tertiary.xlo;
Packit df99a1
      int h = (tertiary.yhi << 8) | tertiary.ylo;
Packit df99a1
      crcb_delay = 0;
Packit df99a1
      crcb_half = 0;
Packit df99a1
      if (secondary.minor>=2)
Packit df99a1
        crcb_delay = tertiary.crcbdelay & 0x7f;
Packit df99a1
      if (secondary.minor>=2)
Packit df99a1
        crcb_half = (tertiary.crcbdelay & 0x80 ? 0 : 1);
Packit df99a1
      if (secondary.major & 0x80)
Packit df99a1
        crcb_delay = -1;
Packit df99a1
      // Create ymap and ycodec    
Packit df99a1
      assert(! ymap);
Packit df99a1
      assert(! ycodec);
Packit df99a1
      ymap = new Map(w, h);
Packit df99a1
      ycodec = new Codec::Decode(*ymap);
Packit df99a1
      if (crcb_delay >= 0)
Packit df99a1
        {
Packit df99a1
          cbmap = new Map(w, h);
Packit df99a1
          crmap = new Map(w, h);
Packit df99a1
          cbcodec = new Codec::Decode(*cbmap);
Packit df99a1
          crcodec = new Codec::Decode(*crmap);
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  // Read data
Packit df99a1
  assert(ymap);
Packit df99a1
  assert(ycodec);
Packit df99a1
  GP<ZPCodec> gzp=ZPCodec::create(gbs, false, true);
Packit df99a1
  ZPCodec &zp=*gzp;
Packit df99a1
  int flag = 1;
Packit df99a1
  while (flag && cslice
Packit df99a1
    {
Packit df99a1
      flag = ycodec->code_slice(zp);
Packit df99a1
      if (crcodec && cbcodec && crcb_delay<=cslice)
Packit df99a1
        {
Packit df99a1
          flag |= cbcodec->code_slice(zp);
Packit df99a1
          flag |= crcodec->code_slice(zp);
Packit df99a1
        }
Packit df99a1
      cslice++;
Packit df99a1
    }
Packit df99a1
  // Return
Packit df99a1
  cserial += 1;
Packit df99a1
  return nslices;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
int 
Packit df99a1
IWPixmap::parm_crcbdelay(const int parm)
Packit df99a1
{
Packit df99a1
  if (parm >= 0)
Packit df99a1
    crcb_delay = parm;
Packit df99a1
  return crcb_delay;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
IWPixmap::parm_dbfrac(float frac)
Packit df99a1
{
Packit df99a1
  if (frac>0 && frac<=1)
Packit df99a1
    db_frac = frac;
Packit df99a1
  else
Packit df99a1
    G_THROW( ERR_MSG("IW44Image.param_range2") );
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
IWPixmap::get_serial(void)
Packit df99a1
{
Packit df99a1
  return cserial;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
void 
Packit df99a1
IWPixmap::decode_iff(IFFByteStream &iff, int maxchunks)
Packit df99a1
{
Packit df99a1
  if (ycodec)
Packit df99a1
    G_THROW( ERR_MSG("IW44Image.left_open4") );
Packit df99a1
  GUTF8String chkid;
Packit df99a1
  iff.get_chunk(chkid);
Packit df99a1
  if (chkid!="FORM:PM44" && chkid!="FORM:BM44")
Packit df99a1
    G_THROW( ERR_MSG("IW44Image.corrupt_BM44_2") );
Packit df99a1
  while (--maxchunks>=0 && iff.get_chunk(chkid))
Packit df99a1
    {
Packit df99a1
      if (chkid=="PM44" || chkid=="BM44")
Packit df99a1
        decode_chunk(iff.get_bytestream());
Packit df99a1
      iff.close_chunk();
Packit df99a1
    }
Packit df99a1
  iff.close_chunk();
Packit df99a1
  close_codec();
Packit df99a1
}
Packit df99a1
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
// NEW FILTERS
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
Packit df99a1
void
Packit df99a1
IW44Image::Transform::filter_begin(int w, int h)
Packit df99a1
{
Packit df99a1
  if (MMXControl::mmxflag < 0)  
Packit df99a1
    MMXControl::enable_mmx();
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
void
Packit df99a1
IW44Image::Transform::filter_end(void)
Packit df99a1
{
Packit df99a1
#ifdef MMX
Packit df99a1
  if (MMXControl::mmxflag > 0)
Packit df99a1
    MMXemms;
Packit df99a1
#endif
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
// WAVELET TRANSFORM 
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
Packit df99a1
Packit df99a1
//----------------------------------------------------
Packit df99a1
// Function for applying bidimensional IW44 between 
Packit df99a1
// scale intervals begin(inclusive) and end(exclusive)
Packit df99a1
Packit df99a1
void
Packit df99a1
IW44Image::Transform::Decode::backward(short *p, int w, int h, int rowsize, int begin, int end)
Packit df99a1
{ 
Packit df99a1
  // PREPARATION
Packit df99a1
  filter_begin(w,h);
Packit df99a1
  // LOOP ON SCALES
Packit df99a1
  for (int scale=begin>>1; scale>=end; scale>>=1)
Packit df99a1
    {
Packit df99a1
#ifdef IWTRANSFORM_TIMER
Packit df99a1
      int tv,th;
Packit df99a1
      th = tv = GOS::ticks();
Packit df99a1
#endif
Packit df99a1
      filter_bv(p, w, h, rowsize, scale);
Packit df99a1
#ifdef IWTRANSFORM_TIMER
Packit df99a1
      th = GOS::ticks();
Packit df99a1
      tv = th - tv;
Packit df99a1
#endif
Packit df99a1
      filter_bh(p, w, h, rowsize, scale);
Packit df99a1
#ifdef IWTRANSFORM_TIMER
Packit df99a1
      th = GOS::ticks()-th;
Packit df99a1
      DjVuPrintErrorUTF8("back%d\tv=%dms h=%dms\n", scale,tv,th);
Packit df99a1
#endif
Packit df99a1
    }
Packit df99a1
  // TERMINATE
Packit df99a1
  filter_end();
Packit df99a1
}
Packit df99a1
  
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
// COLOR TRANSFORM 
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
Packit df99a1
/* Converts YCbCr to RGB. */
Packit df99a1
void 
Packit df99a1
IW44Image::Transform::Decode::YCbCr_to_RGB(GPixel *p, int w, int h, int rowsize)
Packit df99a1
{
Packit df99a1
  for (int i=0; i
Packit df99a1
    {
Packit df99a1
      GPixel *q = p;
Packit df99a1
      for (int j=0; j
Packit df99a1
        {
Packit df99a1
          signed char y = ((signed char*)q)[0];
Packit df99a1
          signed char b = ((signed char*)q)[1];
Packit df99a1
          signed char r = ((signed char*)q)[2];
Packit df99a1
          // This is the Pigeon transform
Packit df99a1
          int t1 = b >> 2 ; 
Packit df99a1
          int t2 = r + (r >> 1);
Packit df99a1
          int t3 = y + 128 - t1;
Packit df99a1
          int tr = y + 128 + t2;
Packit df99a1
          int tg = t3 - (t2 >> 1);
Packit df99a1
          int tb = t3 + (b << 1);
Packit df99a1
          q->r = max(0,min(255,tr));
Packit df99a1
          q->g = max(0,min(255,tg));
Packit df99a1
          q->b = max(0,min(255,tb));
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
}
Packit df99a1
# ifndef NOT_USING_DJVU_NAMESPACE
Packit df99a1
using namespace DJVU;
Packit df99a1
# endif
Packit df99a1
#endif