// Copyright 2015 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fxcodec/jbig2/JBig2_TrdProc.h"

#include <memory>

#include "core/fxcodec/jbig2/JBig2_ArithDecoder.h"
#include "core/fxcodec/jbig2/JBig2_ArithIntDecoder.h"
#include "core/fxcodec/jbig2/JBig2_GrrdProc.h"
#include "core/fxcodec/jbig2/JBig2_HuffmanDecoder.h"

CJBig2_Image* CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream* pStream,
                                             JBig2ArithCtx* grContext) {
  std::unique_ptr<CJBig2_HuffmanDecoder> pHuffmanDecoder(
      new CJBig2_HuffmanDecoder(pStream));
  std::unique_ptr<CJBig2_Image> SBREG(new CJBig2_Image(SBW, SBH));
  SBREG->fill(SBDEFPIXEL);
  int32_t STRIPT;
  if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &STRIPT) != 0)
    return nullptr;

  STRIPT *= SBSTRIPS;
  STRIPT = -STRIPT;
  uint32_t NINSTANCES = 0;
  while (NINSTANCES < SBNUMINSTANCES) {
    int32_t DT;
    if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &DT) != 0)
      return nullptr;

    DT *= SBSTRIPS;
    STRIPT = STRIPT + DT;
    bool bFirst = true;
    int32_t FIRSTS = 0;
    int32_t CURS = 0;
    for (;;) {
      if (bFirst) {
        int32_t DFS;
        if (pHuffmanDecoder->decodeAValue(SBHUFFFS, &DFS) != 0)
          return nullptr;

        FIRSTS = FIRSTS + DFS;
        CURS = FIRSTS;
        bFirst = false;
      } else {
        int32_t IDS;
        int32_t nVal = pHuffmanDecoder->decodeAValue(SBHUFFDS, &IDS);
        if (nVal == JBIG2_OOB) {
          break;
        } else if (nVal != 0) {
          return nullptr;
        } else {
          CURS = CURS + IDS + SBDSOFFSET;
        }
      }
      uint8_t CURT = 0;
      if (SBSTRIPS != 1) {
        uint32_t nTmp = 1;
        while ((uint32_t)(1 << nTmp) < SBSTRIPS) {
          nTmp++;
        }
        int32_t nVal;
        if (pStream->readNBits(nTmp, &nVal) != 0)
          return nullptr;

        CURT = nVal;
      }
      int32_t TI = STRIPT + CURT;
      int32_t nVal = 0;
      int32_t nBits = 0;
      uint32_t IDI;
      for (;;) {
        uint32_t nTmp;
        if (pStream->read1Bit(&nTmp) != 0)
          return nullptr;

        nVal = (nVal << 1) | nTmp;
        nBits++;
        for (IDI = 0; IDI < SBNUMSYMS; IDI++) {
          if ((nBits == SBSYMCODES[IDI].codelen) &&
              (nVal == SBSYMCODES[IDI].code)) {
            break;
          }
        }
        if (IDI < SBNUMSYMS) {
          break;
        }
      }
      FX_BOOL RI = 0;
      if (SBREFINE != 0 && pStream->read1Bit(&RI) != 0) {
        return nullptr;
      }
      CJBig2_Image* IBI = nullptr;
      if (RI == 0) {
        IBI = SBSYMS[IDI];
      } else {
        int32_t RDWI;
        int32_t RDHI;
        int32_t RDXI;
        int32_t RDYI;
        if ((pHuffmanDecoder->decodeAValue(SBHUFFRDW, &RDWI) != 0) ||
            (pHuffmanDecoder->decodeAValue(SBHUFFRDH, &RDHI) != 0) ||
            (pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDXI) != 0) ||
            (pHuffmanDecoder->decodeAValue(SBHUFFRDY, &RDYI) != 0) ||
            (pHuffmanDecoder->decodeAValue(SBHUFFRSIZE, &nVal) != 0)) {
          return nullptr;
        }
        pStream->alignByte();
        uint32_t nTmp = pStream->getOffset();
        CJBig2_Image* IBOI = SBSYMS[IDI];
        if (!IBOI)
          return nullptr;

        uint32_t WOI = IBOI->width();
        uint32_t HOI = IBOI->height();
        if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0)
          return nullptr;

        std::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc());
        pGRRD->GRW = WOI + RDWI;
        pGRRD->GRH = HOI + RDHI;
        pGRRD->GRTEMPLATE = SBRTEMPLATE;
        pGRRD->GRREFERENCE = IBOI;
        pGRRD->GRREFERENCEDX = (RDWI >> 2) + RDXI;
        pGRRD->GRREFERENCEDY = (RDHI >> 2) + RDYI;
        pGRRD->TPGRON = 0;
        pGRRD->GRAT[0] = SBRAT[0];
        pGRRD->GRAT[1] = SBRAT[1];
        pGRRD->GRAT[2] = SBRAT[2];
        pGRRD->GRAT[3] = SBRAT[3];

        {
          std::unique_ptr<CJBig2_ArithDecoder> pArithDecoder(
              new CJBig2_ArithDecoder(pStream));
          IBI = pGRRD->decode(pArithDecoder.get(), grContext);
          if (!IBI)
            return nullptr;
        }

        pStream->alignByte();
        pStream->offset(2);
        if ((uint32_t)nVal != (pStream->getOffset() - nTmp)) {
          delete IBI;
          return nullptr;
        }
      }
      if (!IBI) {
        continue;
      }
      uint32_t WI = IBI->width();
      uint32_t HI = IBI->height();
      if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) ||
                              (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
        CURS = CURS + WI - 1;
      } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) ||
                                     (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
        CURS = CURS + HI - 1;
      }
      int32_t SI = CURS;
      if (TRANSPOSED == 0) {
        switch (REFCORNER) {
          case JBIG2_CORNER_TOPLEFT:
            SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
            break;
          case JBIG2_CORNER_TOPRIGHT:
            SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
            break;
          case JBIG2_CORNER_BOTTOMLEFT:
            SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
            break;
          case JBIG2_CORNER_BOTTOMRIGHT:
            SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
            break;
        }
      } else {
        switch (REFCORNER) {
          case JBIG2_CORNER_TOPLEFT:
            SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
            break;
          case JBIG2_CORNER_TOPRIGHT:
            SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
            break;
          case JBIG2_CORNER_BOTTOMLEFT:
            SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
            break;
          case JBIG2_CORNER_BOTTOMRIGHT:
            SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
            break;
        }
      }
      if (RI != 0) {
        delete IBI;
      }
      if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
                              (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
        CURS = CURS + WI - 1;
      } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
                                     (REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
        CURS = CURS + HI - 1;
      }
      NINSTANCES = NINSTANCES + 1;
    }
  }
  return SBREG.release();
}

CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
                                           JBig2ArithCtx* grContext,
                                           JBig2IntDecoderState* pIDS) {
  std::unique_ptr<CJBig2_ArithIntDecoder> IADT;
  std::unique_ptr<CJBig2_ArithIntDecoder> IAFS;
  std::unique_ptr<CJBig2_ArithIntDecoder> IADS;
  std::unique_ptr<CJBig2_ArithIntDecoder> IAIT;
  std::unique_ptr<CJBig2_ArithIntDecoder> IARI;
  std::unique_ptr<CJBig2_ArithIntDecoder> IARDW;
  std::unique_ptr<CJBig2_ArithIntDecoder> IARDH;
  std::unique_ptr<CJBig2_ArithIntDecoder> IARDX;
  std::unique_ptr<CJBig2_ArithIntDecoder> IARDY;
  std::unique_ptr<CJBig2_ArithIaidDecoder> IAID;
  CJBig2_ArithIntDecoder* pIADT;
  CJBig2_ArithIntDecoder* pIAFS;
  CJBig2_ArithIntDecoder* pIADS;
  CJBig2_ArithIntDecoder* pIAIT;
  CJBig2_ArithIntDecoder* pIARI;
  CJBig2_ArithIntDecoder* pIARDW;
  CJBig2_ArithIntDecoder* pIARDH;
  CJBig2_ArithIntDecoder* pIARDX;
  CJBig2_ArithIntDecoder* pIARDY;
  CJBig2_ArithIaidDecoder* pIAID;
  if (pIDS) {
    pIADT = pIDS->IADT;
    pIAFS = pIDS->IAFS;
    pIADS = pIDS->IADS;
    pIAIT = pIDS->IAIT;
    pIARI = pIDS->IARI;
    pIARDW = pIDS->IARDW;
    pIARDH = pIDS->IARDH;
    pIARDX = pIDS->IARDX;
    pIARDY = pIDS->IARDY;
    pIAID = pIDS->IAID;
  } else {
    IADT.reset(new CJBig2_ArithIntDecoder());
    IAFS.reset(new CJBig2_ArithIntDecoder());
    IADS.reset(new CJBig2_ArithIntDecoder());
    IAIT.reset(new CJBig2_ArithIntDecoder());
    IARI.reset(new CJBig2_ArithIntDecoder());
    IARDW.reset(new CJBig2_ArithIntDecoder());
    IARDH.reset(new CJBig2_ArithIntDecoder());
    IARDX.reset(new CJBig2_ArithIntDecoder());
    IARDY.reset(new CJBig2_ArithIntDecoder());
    IAID.reset(new CJBig2_ArithIaidDecoder(SBSYMCODELEN));
    pIADT = IADT.get();
    pIAFS = IAFS.get();
    pIADS = IADS.get();
    pIAIT = IAIT.get();
    pIARI = IARI.get();
    pIARDW = IARDW.get();
    pIARDH = IARDH.get();
    pIARDX = IARDX.get();
    pIARDY = IARDY.get();
    pIAID = IAID.get();
  }
  std::unique_ptr<CJBig2_Image> SBREG(new CJBig2_Image(SBW, SBH));
  SBREG->fill(SBDEFPIXEL);
  int32_t STRIPT;
  pIADT->decode(pArithDecoder, &STRIPT);
  STRIPT *= SBSTRIPS;
  STRIPT = -STRIPT;
  int32_t FIRSTS = 0;
  uint32_t NINSTANCES = 0;
  while (NINSTANCES < SBNUMINSTANCES) {
    int32_t CURS = 0;
    int32_t DT;
    pIADT->decode(pArithDecoder, &DT);
    DT *= SBSTRIPS;
    STRIPT += DT;
    bool bFirst = true;
    for (;;) {
      if (bFirst) {
        int32_t DFS;
        pIAFS->decode(pArithDecoder, &DFS);
        FIRSTS += DFS;
        CURS = FIRSTS;
        bFirst = false;
      } else {
        int32_t IDS;
        if (!pIADS->decode(pArithDecoder, &IDS))
          break;
        CURS += IDS + SBDSOFFSET;
      }
      if (NINSTANCES >= SBNUMINSTANCES) {
        break;
      }
      int CURT = 0;
      if (SBSTRIPS != 1)
        pIAIT->decode(pArithDecoder, &CURT);

      int32_t TI = STRIPT + CURT;
      uint32_t IDI;
      pIAID->decode(pArithDecoder, &IDI);
      if (IDI >= SBNUMSYMS)
        return nullptr;

      int RI;
      if (SBREFINE == 0)
        RI = 0;
      else
        pIARI->decode(pArithDecoder, &RI);

      std::unique_ptr<CJBig2_Image> IBI;
      CJBig2_Image* pIBI;
      if (RI == 0) {
        pIBI = SBSYMS[IDI];
      } else {
        int32_t RDWI;
        int32_t RDHI;
        int32_t RDXI;
        int32_t RDYI;
        pIARDW->decode(pArithDecoder, &RDWI);
        pIARDH->decode(pArithDecoder, &RDHI);
        pIARDX->decode(pArithDecoder, &RDXI);
        pIARDY->decode(pArithDecoder, &RDYI);
        CJBig2_Image* IBOI = SBSYMS[IDI];
        if (!IBOI)
          return nullptr;

        uint32_t WOI = IBOI->width();
        uint32_t HOI = IBOI->height();
        if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0)
          return nullptr;

        std::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc());
        pGRRD->GRW = WOI + RDWI;
        pGRRD->GRH = HOI + RDHI;
        pGRRD->GRTEMPLATE = SBRTEMPLATE;
        pGRRD->GRREFERENCE = IBOI;
        pGRRD->GRREFERENCEDX = (RDWI >> 1) + RDXI;
        pGRRD->GRREFERENCEDY = (RDHI >> 1) + RDYI;
        pGRRD->TPGRON = 0;
        pGRRD->GRAT[0] = SBRAT[0];
        pGRRD->GRAT[1] = SBRAT[1];
        pGRRD->GRAT[2] = SBRAT[2];
        pGRRD->GRAT[3] = SBRAT[3];
        IBI.reset(pGRRD->decode(pArithDecoder, grContext));
        pIBI = IBI.get();
      }
      if (!pIBI)
        return nullptr;

      uint32_t WI = pIBI->width();
      uint32_t HI = pIBI->height();
      if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) ||
                              (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
        CURS += WI - 1;
      } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) ||
                                     (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
        CURS += HI - 1;
      }
      int32_t SI = CURS;
      if (TRANSPOSED == 0) {
        switch (REFCORNER) {
          case JBIG2_CORNER_TOPLEFT:
            SBREG->composeFrom(SI, TI, pIBI, SBCOMBOP);
            break;
          case JBIG2_CORNER_TOPRIGHT:
            SBREG->composeFrom(SI - WI + 1, TI, pIBI, SBCOMBOP);
            break;
          case JBIG2_CORNER_BOTTOMLEFT:
            SBREG->composeFrom(SI, TI - HI + 1, pIBI, SBCOMBOP);
            break;
          case JBIG2_CORNER_BOTTOMRIGHT:
            SBREG->composeFrom(SI - WI + 1, TI - HI + 1, pIBI, SBCOMBOP);
            break;
        }
      } else {
        switch (REFCORNER) {
          case JBIG2_CORNER_TOPLEFT:
            SBREG->composeFrom(TI, SI, pIBI, SBCOMBOP);
            break;
          case JBIG2_CORNER_TOPRIGHT:
            SBREG->composeFrom(TI - WI + 1, SI, pIBI, SBCOMBOP);
            break;
          case JBIG2_CORNER_BOTTOMLEFT:
            SBREG->composeFrom(TI, SI - HI + 1, pIBI, SBCOMBOP);
            break;
          case JBIG2_CORNER_BOTTOMRIGHT:
            SBREG->composeFrom(TI - WI + 1, SI - HI + 1, pIBI, SBCOMBOP);
            break;
        }
      }
      if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
                              (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
        CURS += WI - 1;
      } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
                                     (REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
        CURS += HI - 1;
      }
      ++NINSTANCES;
    }
  }
  return SBREG.release();
}
