// 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(FX_LPBYTE pData, FX_DWORD size)
{
    FX_INT32 width, height, color_trans, num_comps, bits;
    if (!CPDF_ModuleMgr::Get()->GetJpegModule()->
            LoadInfo(pData, size, width, height, num_comps, bits, color_trans)) {
        return NULL;
    }
    CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary;
    pDict->SetAtName("Type", "XObject");
    pDict->SetAtName("Subtype", "Image");
    pDict->SetAtInteger("Width", width);
    pDict->SetAtInteger("Height", height);
    FX_LPCSTR 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 = FX_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 = FX_NEW CPDF_Stream(NULL, 0, NULL);
    }
    return pDict;
}
void CPDF_Image::SetJpegImage(FX_LPBYTE 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;
    }
    FX_LPBYTE pData = FX_Alloc(FX_BYTE, dwEstimateSize);
    if (!pData) {
        return;
    }
    pFile->ReadBlock(pData, 0, dwEstimateSize);
    CPDF_Dictionary *pDict = InitJPEG(pData, dwEstimateSize);
    FX_Free(pData);
    if (!pDict && size > dwEstimateSize) {
        pData = FX_Alloc(FX_BYTE, size);
        if (!pData) {
            return;
        }
        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, FX_LPBYTE &buf, FX_STRSIZE &size)
{
}
void _JBIG2EncodeBitmap(CPDF_Dictionary *pBitmapDict, const CFX_DIBitmap *pBitmap, CPDF_Document *pDoc, FX_LPBYTE &buf, FX_STRSIZE &size, FX_BOOL bLossLess)
{
}
void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, FX_INT32 iCompress, IFX_FileWrite *pFileWrite, IFX_FileRead *pFileRead, const CFX_DIBitmap* pMask, const CPDF_ImageSetParam* pParam)
{
    FX_INT32 BitmapWidth = pBitmap->GetWidth();
    FX_INT32 BitmapHeight = pBitmap->GetHeight();
    if (BitmapWidth < 1 || BitmapHeight < 1) {
        return;
    }
    FX_LPBYTE src_buf = pBitmap->GetBuffer();
    FX_INT32 src_pitch = pBitmap->GetPitch();
    FX_INT32 bpp = pBitmap->GetBPP();
    FX_BOOL bUseMatte = pParam && pParam->pMatteColor && (pBitmap->GetFormat() == FXDIB_Argb);
    CPDF_Dictionary* pDict = FX_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);
    FX_LPBYTE dest_buf = NULL;
    FX_STRSIZE dest_pitch = 0, dest_size = 0, opType = -1;
    if (bpp == 1) {
        FX_INT32 reset_a = 0, reset_r = 0, reset_g = 0, reset_b = 0;
        FX_INT32 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"), FX_NEW CPDF_Boolean(TRUE));
            if (reset_a == 0) {
                CPDF_Array* pArray = FX_NEW CPDF_Array;
                pArray->AddInteger(1);
                pArray->AddInteger(0);
                pDict->SetAt(FX_BSTRC("Decode"), pArray);
            }
        } else {
            CPDF_Array* pCS = FX_NEW CPDF_Array;
            pCS->AddName(FX_BSTRC("Indexed"));
            pCS->AddName(FX_BSTRC("DeviceRGB"));
            pCS->AddInteger(1);
            CFX_ByteString ct;
            FX_LPSTR 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) {
        FX_INT32 iPalette = pBitmap->GetPaletteSize();
        if (iPalette > 0) {
            CPDF_Array* pCS = FX_NEW CPDF_Array;
            m_pDocument->AddIndirectObject(pCS);
            pCS->AddName(FX_BSTRC("Indexed"));
            pCS->AddName(FX_BSTRC("DeviceRGB"));
            pCS->AddInteger(iPalette - 1);
            FX_LPBYTE pColorTable = FX_Alloc(FX_BYTE, iPalette * 3);
            FX_LPBYTE ptr = pColorTable;
            for (FX_INT32 i = 0; i < iPalette; i ++) {
                FX_DWORD argb = pBitmap->GetPaletteArgb(i);
                ptr[0] = (FX_BYTE)(argb >> 16);
                ptr[1] = (FX_BYTE)(argb >> 8);
                ptr[2] = (FX_BYTE)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;
    if (pBitmap->HasAlpha()) {
        pMaskBitmap = pBitmap->GetAlphaMask();
    }
    if (!pMaskBitmap && pMask) {
        FXDIB_Format maskFormat = pMask->GetFormat();
        if (maskFormat == FXDIB_1bppMask || maskFormat == FXDIB_8bppMask) {
            pMaskBitmap = pMask;
        }
    }
    if (pMaskBitmap) {
        FX_INT32 maskWidth = pMaskBitmap->GetWidth();
        FX_INT32 maskHeight = pMaskBitmap->GetHeight();
        FX_LPBYTE mask_buf = NULL;
        FX_STRSIZE mask_size;
        FX_BOOL bDeleteMask = TRUE;
        CPDF_Dictionary* pMaskDict = FX_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_size = maskHeight * maskWidth;
            mask_buf = FX_Alloc(FX_BYTE, mask_size);
            for (FX_INT32 a = 0; a < maskHeight; a ++) {
                FXSYS_memcpy32(mask_buf + a * maskWidth, pMaskBitmap->GetScanline(a), maskWidth);
            }
        }
        if (pMaskDict) {
            pMaskDict->SetAtInteger(FX_BSTRC("Length"), mask_size);
            CPDF_Stream* pMaskStream = NULL;
            if (bUseMatte) {
                int a, r, g, b;
                ArgbDecode(*(pParam->pMatteColor), a, r, g, b);
                CPDF_Array* pMatte = FX_NEW CPDF_Array;
                pMatte->AddInteger(r);
                pMatte->AddInteger(g);
                pMatte->AddInteger(b);
                pMaskDict->SetAt(FX_BSTRC("Matte"), pMatte);
            }
            pMaskStream = FX_NEW CPDF_Stream(mask_buf, mask_size, pMaskDict);
            m_pDocument->AddIndirectObject(pMaskStream);
            bDeleteMask = FALSE;
            pDict->SetAtReference(FX_BSTRC("SMask"), m_pDocument, pMaskStream);
        }
        if (pBitmap->HasAlpha()) {
            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 = FX_NEW CFX_DIBitmap();
                pNewBitmap->Copy(pBitmap);
                pNewBitmap->ConvertFormat(FXDIB_Rgb);
                SetImage(pNewBitmap, iCompress, pFileWrite, pFileRead);
                if (pDict) {
                    pDict->Release();
                    pDict = NULL;
                }
                if (dest_buf) {
                    FX_Free(dest_buf);
                    dest_buf = NULL;
                }
                dest_size = 0;
                delete pNewBitmap;
                return;
            } else {
                if (bUseMatte) {
                    CFX_DIBitmap *pNewBitmap = FX_NEW CFX_DIBitmap();
                    pNewBitmap->Create(BitmapWidth, BitmapHeight, FXDIB_Argb);
                    FX_LPBYTE dst_buf = pNewBitmap->GetBuffer();
                    FX_INT32 src_offset = 0;
                    for (FX_INT32 row = 0; row < BitmapHeight; row ++) {
                        src_offset = row * src_pitch;
                        for (FX_INT32 column = 0; column < BitmapWidth; column ++) {
                            FX_FLOAT alpha = src_buf[src_offset + 3] / 255.0f;
                            dst_buf[src_offset] = (FX_BYTE)(src_buf[src_offset] * alpha);
                            dst_buf[src_offset + 1] = (FX_BYTE)(src_buf[src_offset + 1] * alpha);
                            dst_buf[src_offset + 2] = (FX_BYTE)(src_buf[src_offset + 2] * alpha);
                            dst_buf[src_offset + 3] = (FX_BYTE)(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_size = dest_pitch * BitmapHeight;
            dest_buf = FX_Alloc(FX_BYTE, dest_size);
        }
        FX_LPBYTE pDest = dest_buf;
        for (FX_INT32 i = 0; i < BitmapHeight; i ++) {
            if (!bStream) {
                FXSYS_memcpy32(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_size = dest_pitch * BitmapHeight;
            dest_buf = FX_Alloc(FX_BYTE, dest_size);
        } else {
            dest_buf = FX_Alloc(FX_BYTE, dest_pitch);
        }
        FX_LPBYTE pDest = dest_buf;
        FX_INT32 src_offset = 0;
        FX_INT32 dest_offset = 0;
        for (FX_INT32 row = 0; row < BitmapHeight; row ++) {
            src_offset = row * src_pitch;
            for (FX_INT32 column = 0; column < BitmapWidth; column ++) {
                FX_FLOAT alpha = bUseMatte ? src_buf[src_offset + 3] / 255.0f : 1;
                pDest[dest_offset] = (FX_BYTE)(src_buf[src_offset + 2] * alpha);
                pDest[dest_offset + 1] = (FX_BYTE)(src_buf[src_offset + 1] * alpha);
                pDest[dest_offset + 2] = (FX_BYTE)(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 = FX_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;
    if (dest_buf) {
        FX_Free(dest_buf);
    }
}
void CPDF_Image::ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pBitmap)
{
    pPage->GetRenderCache()->ResetBitmap(m_pStream, pBitmap);
}
