// Copyright 2014 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 "../../../include/fpdfapi/fpdf_module.h"
#include "../../../include/fpdfapi/fpdf_page.h"
#include "../../../include/fxcodec/fx_codec.h"
#include "../../../include/fpdfapi/fpdf_render.h"
#include "../fpdf_page/pageint.h"
#include "../fpdf_render/render_int.h"
CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, FX_DWORD size) {
  int32_t width;
  int32_t height;
  int32_t num_comps;
  int32_t bits;
  FX_BOOL color_trans;
  if (!CPDF_ModuleMgr::Get()->GetJpegModule()->LoadInfo(
          pData, size, width, height, num_comps, bits, color_trans)) {
    return NULL;
  }
  CPDF_Dictionary* pDict = new CPDF_Dictionary;
  pDict->SetAtName("Type", "XObject");
  pDict->SetAtName("Subtype", "Image");
  pDict->SetAtInteger("Width", width);
  pDict->SetAtInteger("Height", height);
  const FX_CHAR* csname = NULL;
  if (num_comps == 1) {
    csname = "DeviceGray";
  } else if (num_comps == 3) {
    csname = "DeviceRGB";
  } else if (num_comps == 4) {
    csname = "DeviceCMYK";
    CPDF_Array* pDecode = CPDF_Array::Create();
    for (int n = 0; n < 4; n++) {
      pDecode->AddInteger(1);
      pDecode->AddInteger(0);
    }
    pDict->SetAt(FX_BSTRC("Decode"), pDecode);
  }
  pDict->SetAtName("ColorSpace", csname);
  pDict->SetAtInteger("BitsPerComponent", bits);
  pDict->SetAtName("Filter", "DCTDecode");
  if (!color_trans) {
    CPDF_Dictionary* pParms = new CPDF_Dictionary;
    pDict->SetAt("DecodeParms", pParms);
    pParms->SetAtInteger("ColorTransform", 0);
  }
  m_bIsMask = FALSE;
  m_Width = width;
  m_Height = height;
  if (m_pStream == NULL) {
    m_pStream = new CPDF_Stream(NULL, 0, NULL);
  }
  return pDict;
}
void CPDF_Image::SetJpegImage(uint8_t* pData, FX_DWORD size) {
  CPDF_Dictionary* pDict = InitJPEG(pData, size);
  if (!pDict) {
    return;
  }
  m_pStream->InitStream(pData, size, pDict);
}
void CPDF_Image::SetJpegImage(IFX_FileRead* pFile) {
  FX_DWORD size = (FX_DWORD)pFile->GetSize();
  if (!size) {
    return;
  }
  FX_DWORD dwEstimateSize = size;
  if (dwEstimateSize > 8192) {
    dwEstimateSize = 8192;
  }
  uint8_t* pData = FX_Alloc(uint8_t, dwEstimateSize);
  pFile->ReadBlock(pData, 0, dwEstimateSize);
  CPDF_Dictionary* pDict = InitJPEG(pData, dwEstimateSize);
  FX_Free(pData);
  if (!pDict && size > dwEstimateSize) {
    pData = FX_Alloc(uint8_t, size);
    pFile->ReadBlock(pData, 0, size);
    pDict = InitJPEG(pData, size);
    FX_Free(pData);
  }
  if (!pDict) {
    return;
  }
  m_pStream->InitStream(pFile, pDict);
}
void _DCTEncodeBitmap(CPDF_Dictionary* pBitmapDict,
                      const CFX_DIBitmap* pBitmap,
                      int quality,
                      uint8_t*& buf,
                      FX_STRSIZE& size) {}
void _JBIG2EncodeBitmap(CPDF_Dictionary* pBitmapDict,
                        const CFX_DIBitmap* pBitmap,
                        CPDF_Document* pDoc,
                        uint8_t*& buf,
                        FX_STRSIZE& size,
                        FX_BOOL bLossLess) {}
void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap,
                          int32_t iCompress,
                          IFX_FileWrite* pFileWrite,
                          IFX_FileRead* pFileRead,
                          const CFX_DIBitmap* pMask,
                          const CPDF_ImageSetParam* pParam) {
  int32_t BitmapWidth = pBitmap->GetWidth();
  int32_t BitmapHeight = pBitmap->GetHeight();
  if (BitmapWidth < 1 || BitmapHeight < 1) {
    return;
  }
  uint8_t* src_buf = pBitmap->GetBuffer();
  int32_t src_pitch = pBitmap->GetPitch();
  int32_t bpp = pBitmap->GetBPP();
  FX_BOOL bUseMatte =
      pParam && pParam->pMatteColor && (pBitmap->GetFormat() == FXDIB_Argb);
  CPDF_Dictionary* pDict = new CPDF_Dictionary;
  pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("XObject"));
  pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Image"));
  pDict->SetAtInteger(FX_BSTRC("Width"), BitmapWidth);
  pDict->SetAtInteger(FX_BSTRC("Height"), BitmapHeight);
  uint8_t* dest_buf = NULL;
  FX_STRSIZE dest_pitch = 0, dest_size = 0, opType = -1;
  if (bpp == 1) {
    int32_t reset_a = 0, reset_r = 0, reset_g = 0, reset_b = 0;
    int32_t set_a = 0, set_r = 0, set_g = 0, set_b = 0;
    if (!pBitmap->IsAlphaMask()) {
      ArgbDecode(pBitmap->GetPaletteArgb(0), reset_a, reset_r, reset_g,
                 reset_b);
      ArgbDecode(pBitmap->GetPaletteArgb(1), set_a, set_r, set_g, set_b);
    }
    if (set_a == 0 || reset_a == 0) {
      pDict->SetAt(FX_BSTRC("ImageMask"), new CPDF_Boolean(TRUE));
      if (reset_a == 0) {
        CPDF_Array* pArray = new CPDF_Array;
        pArray->AddInteger(1);
        pArray->AddInteger(0);
        pDict->SetAt(FX_BSTRC("Decode"), pArray);
      }
    } else {
      CPDF_Array* pCS = new CPDF_Array;
      pCS->AddName(FX_BSTRC("Indexed"));
      pCS->AddName(FX_BSTRC("DeviceRGB"));
      pCS->AddInteger(1);
      CFX_ByteString ct;
      FX_CHAR* pBuf = ct.GetBuffer(6);
      pBuf[0] = (FX_CHAR)reset_r;
      pBuf[1] = (FX_CHAR)reset_g;
      pBuf[2] = (FX_CHAR)reset_b;
      pBuf[3] = (FX_CHAR)set_r;
      pBuf[4] = (FX_CHAR)set_g;
      pBuf[5] = (FX_CHAR)set_b;
      ct.ReleaseBuffer(6);
      pCS->Add(CPDF_String::Create(ct, TRUE));
      pDict->SetAt(FX_BSTRC("ColorSpace"), pCS);
    }
    pDict->SetAtInteger(FX_BSTRC("BitsPerComponent"), 1);
    dest_pitch = (BitmapWidth + 7) / 8;
    if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) {
      opType = 1;
    } else {
      opType = 0;
    }
  } else if (bpp == 8) {
    int32_t iPalette = pBitmap->GetPaletteSize();
    if (iPalette > 0) {
      CPDF_Array* pCS = new CPDF_Array;
      m_pDocument->AddIndirectObject(pCS);
      pCS->AddName(FX_BSTRC("Indexed"));
      pCS->AddName(FX_BSTRC("DeviceRGB"));
      pCS->AddInteger(iPalette - 1);
      uint8_t* pColorTable = FX_Alloc2D(uint8_t, iPalette, 3);
      uint8_t* ptr = pColorTable;
      for (int32_t i = 0; i < iPalette; i++) {
        FX_DWORD argb = pBitmap->GetPaletteArgb(i);
        ptr[0] = (uint8_t)(argb >> 16);
        ptr[1] = (uint8_t)(argb >> 8);
        ptr[2] = (uint8_t)argb;
        ptr += 3;
      }
      CPDF_Stream* pCTS = CPDF_Stream::Create(pColorTable, iPalette * 3,
                                              CPDF_Dictionary::Create());
      m_pDocument->AddIndirectObject(pCTS);
      pCS->AddReference(m_pDocument, pCTS);
      pDict->SetAtReference(FX_BSTRC("ColorSpace"), m_pDocument, pCS);
    } else {
      pDict->SetAtName(FX_BSTRC("ColorSpace"), FX_BSTRC("DeviceGray"));
    }
    pDict->SetAtInteger(FX_BSTRC("BitsPerComponent"), 8);
    if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) {
      dest_pitch = BitmapWidth;
      opType = 1;
    } else {
      opType = 0;
    }
  } else {
    pDict->SetAtName(FX_BSTRC("ColorSpace"), FX_BSTRC("DeviceRGB"));
    pDict->SetAtInteger(FX_BSTRC("BitsPerComponent"), 8);
    if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) {
      dest_pitch = BitmapWidth * 3;
      opType = 2;
    } else {
      opType = 0;
    }
  }
  const CFX_DIBitmap* pMaskBitmap = NULL;
  FX_BOOL bDeleteMask = FALSE;
  if (pBitmap->HasAlpha()) {
    pMaskBitmap = pBitmap->GetAlphaMask();
    bDeleteMask = TRUE;
  }
  if (!pMaskBitmap && pMask) {
    FXDIB_Format maskFormat = pMask->GetFormat();
    if (maskFormat == FXDIB_1bppMask || maskFormat == FXDIB_8bppMask) {
      pMaskBitmap = pMask;
    }
  }
  if (pMaskBitmap) {
    int32_t maskWidth = pMaskBitmap->GetWidth();
    int32_t maskHeight = pMaskBitmap->GetHeight();
    uint8_t* mask_buf = NULL;
    FX_STRSIZE mask_size;
    CPDF_Dictionary* pMaskDict = new CPDF_Dictionary;
    pMaskDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("XObject"));
    pMaskDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Image"));
    pMaskDict->SetAtInteger(FX_BSTRC("Width"), maskWidth);
    pMaskDict->SetAtInteger(FX_BSTRC("Height"), maskHeight);
    pMaskDict->SetAtName(FX_BSTRC("ColorSpace"), FX_BSTRC("DeviceGray"));
    pMaskDict->SetAtInteger(FX_BSTRC("BitsPerComponent"), 8);
    if (pMaskBitmap->GetBPP() == 8 &&
        (iCompress & PDF_IMAGE_MASK_LOSSY_COMPRESS) != 0) {
      _DCTEncodeBitmap(pMaskDict, pMaskBitmap, pParam ? pParam->nQuality : 75,
                       mask_buf, mask_size);
    } else if (pMaskBitmap->GetFormat() == FXDIB_1bppMask) {
      _JBIG2EncodeBitmap(pMaskDict, pMaskBitmap, m_pDocument, mask_buf,
                         mask_size, TRUE);
    } else {
      mask_buf = FX_Alloc2D(uint8_t, maskHeight, maskWidth);
      mask_size = maskHeight * maskWidth;  // Safe since checked alloc returned.
      for (int32_t a = 0; a < maskHeight; a++) {
        FXSYS_memcpy(mask_buf + a * maskWidth, pMaskBitmap->GetScanline(a),
                     maskWidth);
      }
    }
    pMaskDict->SetAtInteger(FX_BSTRC("Length"), mask_size);
    if (bUseMatte) {
      int a, r, g, b;
      ArgbDecode(*(pParam->pMatteColor), a, r, g, b);
      CPDF_Array* pMatte = new CPDF_Array;
      pMatte->AddInteger(r);
      pMatte->AddInteger(g);
      pMatte->AddInteger(b);
      pMaskDict->SetAt(FX_BSTRC("Matte"), pMatte);
    }
    CPDF_Stream* pMaskStream = new CPDF_Stream(mask_buf, mask_size, pMaskDict);
    m_pDocument->AddIndirectObject(pMaskStream);
    pDict->SetAtReference(FX_BSTRC("SMask"), m_pDocument, pMaskStream);
    if (bDeleteMask) {
      delete pMaskBitmap;
    }
  }
  FX_BOOL bStream = pFileWrite != NULL && pFileRead != NULL;
  if (opType == 0) {
    if (iCompress & PDF_IMAGE_LOSSLESS_COMPRESS) {
      if (pBitmap->GetBPP() == 1) {
        _JBIG2EncodeBitmap(pDict, pBitmap, m_pDocument, dest_buf, dest_size,
                           TRUE);
      }
    } else {
      if (pBitmap->GetBPP() == 1) {
        _JBIG2EncodeBitmap(pDict, pBitmap, m_pDocument, dest_buf, dest_size,
                           FALSE);
      } else if (pBitmap->GetBPP() >= 8 && pBitmap->GetPalette() != NULL) {
        CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap();
        pNewBitmap->Copy(pBitmap);
        pNewBitmap->ConvertFormat(FXDIB_Rgb);
        SetImage(pNewBitmap, iCompress, pFileWrite, pFileRead);
        if (pDict) {
          pDict->Release();
          pDict = NULL;
        }
        FX_Free(dest_buf);
        dest_buf = NULL;
        dest_size = 0;
        delete pNewBitmap;
        return;
      } else {
        if (bUseMatte) {
          CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap();
          pNewBitmap->Create(BitmapWidth, BitmapHeight, FXDIB_Argb);
          uint8_t* dst_buf = pNewBitmap->GetBuffer();
          int32_t src_offset = 0;
          for (int32_t row = 0; row < BitmapHeight; row++) {
            src_offset = row * src_pitch;
            for (int32_t column = 0; column < BitmapWidth; column++) {
              FX_FLOAT alpha = src_buf[src_offset + 3] / 255.0f;
              dst_buf[src_offset] = (uint8_t)(src_buf[src_offset] * alpha);
              dst_buf[src_offset + 1] =
                  (uint8_t)(src_buf[src_offset + 1] * alpha);
              dst_buf[src_offset + 2] =
                  (uint8_t)(src_buf[src_offset + 2] * alpha);
              dst_buf[src_offset + 3] = (uint8_t)(src_buf[src_offset + 3]);
              src_offset += 4;
            }
          }
          _DCTEncodeBitmap(pDict, pNewBitmap, pParam ? pParam->nQuality : 75,
                           dest_buf, dest_size);
          delete pNewBitmap;
        } else {
          _DCTEncodeBitmap(pDict, pBitmap, pParam ? pParam->nQuality : 75,
                           dest_buf, dest_size);
        }
      }
    }
    if (bStream) {
      pFileWrite->WriteBlock(dest_buf, dest_size);
      FX_Free(dest_buf);
      dest_buf = NULL;
    }
  } else if (opType == 1) {
    if (!bStream) {
      dest_buf = FX_Alloc2D(uint8_t, dest_pitch, BitmapHeight);
      dest_size =
          dest_pitch * BitmapHeight;  // Safe since checked alloc returned.
    }
    uint8_t* pDest = dest_buf;
    for (int32_t i = 0; i < BitmapHeight; i++) {
      if (!bStream) {
        FXSYS_memcpy(pDest, src_buf, dest_pitch);
        pDest += dest_pitch;
      } else {
        pFileWrite->WriteBlock(src_buf, dest_pitch);
      }
      src_buf += src_pitch;
    }
  } else if (opType == 2) {
    if (!bStream) {
      dest_buf = FX_Alloc2D(uint8_t, dest_pitch, BitmapHeight);
      dest_size =
          dest_pitch * BitmapHeight;  // Safe since checked alloc returned.
    } else {
      dest_buf = FX_Alloc(uint8_t, dest_pitch);
    }
    uint8_t* pDest = dest_buf;
    int32_t src_offset = 0;
    int32_t dest_offset = 0;
    for (int32_t row = 0; row < BitmapHeight; row++) {
      src_offset = row * src_pitch;
      for (int32_t column = 0; column < BitmapWidth; column++) {
        FX_FLOAT alpha = bUseMatte ? src_buf[src_offset + 3] / 255.0f : 1;
        pDest[dest_offset] = (uint8_t)(src_buf[src_offset + 2] * alpha);
        pDest[dest_offset + 1] = (uint8_t)(src_buf[src_offset + 1] * alpha);
        pDest[dest_offset + 2] = (uint8_t)(src_buf[src_offset] * alpha);
        dest_offset += 3;
        src_offset += bpp == 24 ? 3 : 4;
      }
      if (bStream) {
        pFileWrite->WriteBlock(pDest, dest_pitch);
        pDest = dest_buf;
      } else {
        pDest += dest_pitch;
      }
      dest_offset = 0;
    }
    if (bStream) {
      FX_Free(dest_buf);
      dest_buf = NULL;
    }
  }
  if (m_pStream == NULL) {
    m_pStream = new CPDF_Stream(NULL, 0, NULL);
  }
  if (!bStream) {
    m_pStream->InitStream(dest_buf, dest_size, pDict);
  } else {
    pFileWrite->Flush();
    m_pStream->InitStream(pFileRead, pDict);
  }
  m_bIsMask = pBitmap->IsAlphaMask();
  m_Width = BitmapWidth;
  m_Height = BitmapHeight;
  FX_Free(dest_buf);
}
void CPDF_Image::ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pBitmap) {
  pPage->GetRenderCache()->ResetBitmap(m_pStream, pBitmap);
}
