// 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_pageobj.h"
#include "../../../include/fpdfapi/fpdf_render.h"
#include "../../../include/fxcodec/fx_codec.h"
#include "../../../include/fxcrt/fx_safe_types.h"
#include "../../../include/fxge/fx_ge.h"
#include "../fpdf_page/pageint.h"
#include "render_int.h"

bool CPDF_RenderStatus::ProcessImage(CPDF_ImageObject* pImageObj, const CFX_AffineMatrix* pObj2Device)
{
    CPDF_ImageRenderer render;
    if (render.Start(this, pImageObj, pObj2Device, m_bStdCS, m_curBlend)) {
        render.Continue(NULL);
    }
    return render.m_Result;
}
void CPDF_RenderStatus::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap, int left, int top, FX_ARGB mask_argb,
        int bitmap_alpha, int blend_mode, int Transparency)
{
    if (pDIBitmap == NULL) {
        return;
    }
    bool bIsolated = Transparency & PDFTRANS_ISOLATED;
    bool bGroup = Transparency & PDFTRANS_GROUP;
    if (blend_mode == FXDIB_BLEND_NORMAL) {
        if (!pDIBitmap->IsAlphaMask()) {
            if (bitmap_alpha < 255) {
                pDIBitmap->MultiplyAlpha(bitmap_alpha);
            }
            if (m_pDevice->SetDIBits(pDIBitmap, left, top)) {
                return;
            }
        } else {
            FX_DWORD fill_argb = m_Options.TranslateColor(mask_argb);
            if (bitmap_alpha < 255) {
                ((uint8_t*)&fill_argb)[3] = ((uint8_t*)&fill_argb)[3] * bitmap_alpha / 255;
            }
            if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) {
                return;
            }
        }
    }
    bool bBackAlphaRequired = blend_mode && bIsolated && !m_bDropObjects;
    bool bGetBackGround = ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) ||
                             (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) && (m_pDevice->GetRenderCaps()
                                     & FXRC_GET_BITS) && !bBackAlphaRequired);
    if (bGetBackGround) {
        if (bIsolated || !bGroup) {
            if (pDIBitmap->IsAlphaMask()) {
                return;
            }
            m_pDevice->SetDIBits(pDIBitmap, left, top, blend_mode);
        } else {
            FX_RECT rect(left, top, left + pDIBitmap->GetWidth(), top + pDIBitmap->GetHeight());
            rect.Intersect(m_pDevice->GetClipBox());
            CFX_DIBitmap* pClone = NULL;
            bool bClone = false;
            if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) {
                bClone = true;
                pClone = m_pDevice->GetBackDrop()->Clone(&rect);
                CFX_DIBitmap *pForeBitmap = m_pDevice->GetBitmap();
                pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(), pForeBitmap, rect.left, rect.top);
                left = left >= 0 ? 0 : left;
                top = top >= 0 ? 0 : top;
                if (!pDIBitmap->IsAlphaMask())
                    pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(), pDIBitmap,
                                            left, top, blend_mode);
                else
                    pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(), pDIBitmap,
                                          mask_argb, left, top, blend_mode);
            } else {
                pClone = pDIBitmap;
            }
            if (m_pDevice->GetBackDrop()) {
                m_pDevice->SetDIBits(pClone, rect.left, rect.top);
            } else {
                if (pDIBitmap->IsAlphaMask()) {
                    return;
                }
                m_pDevice->SetDIBits(pDIBitmap, rect.left, rect.top, blend_mode);
            }
            if (bClone) {
                delete pClone;
            }
        }
        return;
    }
    int back_left, back_top;
    FX_RECT rect(left, top, left + pDIBitmap->GetWidth(), top + pDIBitmap->GetHeight());
    CFX_DIBitmap* pBackdrop = GetBackdrop(m_pCurObj, rect, back_left, back_top, blend_mode > FXDIB_BLEND_NORMAL && bIsolated);
    if (!pBackdrop) {
        return;
    }
    if (!pDIBitmap->IsAlphaMask())
        pBackdrop->CompositeBitmap(left - back_left, top - back_top, pDIBitmap->GetWidth(), pDIBitmap->GetHeight(), pDIBitmap,
                                   0, 0, blend_mode);
    else
        pBackdrop->CompositeMask(left - back_left, top - back_top, pDIBitmap->GetWidth(), pDIBitmap->GetHeight(), pDIBitmap,
                                 mask_argb, 0, 0, blend_mode);
    CFX_DIBitmap* pBackdrop1 = new CFX_DIBitmap;
    pBackdrop1->Create(pBackdrop->GetWidth(), pBackdrop->GetHeight(), FXDIB_Rgb32);
    pBackdrop1->Clear((FX_DWORD) - 1);
    pBackdrop1->CompositeBitmap(0, 0, pBackdrop->GetWidth(), pBackdrop->GetHeight(), pBackdrop, 0, 0);
    delete pBackdrop;
    pBackdrop = pBackdrop1;
    m_pDevice->SetDIBits(pBackdrop, back_left, back_top);
    delete pBackdrop;
}
FX_COLORREF CPDF_TransferFunc::TranslateColor(FX_COLORREF rgb)
{
    return FXSYS_RGB(m_Samples[FXSYS_GetRValue(rgb)], m_Samples[256 + FXSYS_GetGValue(rgb)],
                     m_Samples[512 + FXSYS_GetBValue(rgb)]);
}
CFX_DIBSource* CPDF_TransferFunc::TranslateImage(const CFX_DIBSource* pSrc, bool bAutoDropSrc)
{
    CPDF_DIBTransferFunc* pDest = new CPDF_DIBTransferFunc(this);
    pDest->LoadSrc(pSrc, bAutoDropSrc);
    return pDest;
}
FXDIB_Format CPDF_DIBTransferFunc::GetDestFormat()
{
    if (m_pSrc->IsAlphaMask()) {
        return FXDIB_8bppMask;
    }
#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
    return (m_pSrc->HasAlpha()) ? FXDIB_Argb : FXDIB_Rgb32;
#else
    return (m_pSrc->HasAlpha()) ? FXDIB_Argb : FXDIB_Rgb;
#endif
}
CPDF_DIBTransferFunc::CPDF_DIBTransferFunc(const CPDF_TransferFunc* pTransferFunc)
{
    m_RampR = pTransferFunc->m_Samples;
    m_RampG = &pTransferFunc->m_Samples[256];
    m_RampB = &pTransferFunc->m_Samples[512];
}
void CPDF_DIBTransferFunc::TranslateScanline(uint8_t* dest_buf, const uint8_t* src_buf) const
{
    int i;
    bool bSkip = false;
    switch (m_pSrc->GetFormat()) {
        case FXDIB_1bppRgb: {
                int r0 = m_RampR[0], g0 = m_RampG[0], b0 = m_RampB[0];
                int r1 = m_RampR[255], g1 = m_RampG[255], b1 = m_RampB[255];
                for (i = 0; i < m_Width; i ++) {
                    if (src_buf[i / 8] & (1 << (7 - i % 8))) {
                        *dest_buf++ = b1;
                        *dest_buf++ = g1;
                        *dest_buf++ = r1;
                    } else {
                        *dest_buf++ = b0;
                        *dest_buf++ = g0;
                        *dest_buf++ = r0;
                    }
#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
                    dest_buf++;
#endif
                }
                break;
            }
        case FXDIB_1bppMask: {
                int m0 = m_RampR[0], m1 = m_RampR[255];
                for (i = 0; i < m_Width; i ++) {
                    if (src_buf[i / 8] & (1 << (7 - i % 8))) {
                        *dest_buf++ = m1;
                    } else {
                        *dest_buf++ = m0;
                    }
                }
                break;
            }
        case FXDIB_8bppRgb: {
                FX_ARGB* pPal = m_pSrc->GetPalette();
                for (i = 0; i < m_Width; i ++) {
                    if (pPal) {
                        FX_ARGB src_argb = pPal[*src_buf];
                        *dest_buf++ = m_RampB[FXARGB_R(src_argb)];
                        *dest_buf++ = m_RampG[FXARGB_G(src_argb)];
                        *dest_buf++ = m_RampR[FXARGB_B(src_argb)];
                    } else {
                        FX_DWORD src_byte = *src_buf;
                        *dest_buf++ = m_RampB[src_byte];
                        *dest_buf++ = m_RampG[src_byte];
                        *dest_buf++ = m_RampR[src_byte];
                    }
                    src_buf ++;
#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
                    dest_buf++;
#endif
                }
                break;
            }
        case FXDIB_8bppMask:
            for (i = 0; i < m_Width; i ++) {
                *dest_buf++ = m_RampR[*(src_buf++)];
            }
            break;
        case FXDIB_Rgb:
            for (i = 0; i < m_Width; i ++) {
                *dest_buf++ = m_RampB[*(src_buf++)];
                *dest_buf++ = m_RampG[*(src_buf++)];
                *dest_buf++ = m_RampR[*(src_buf++)];
#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
                dest_buf++;
#endif
            }
            break;
        case FXDIB_Rgb32:
            bSkip = true;
        case FXDIB_Argb:
            for (i = 0; i < m_Width; i ++) {
                *dest_buf++ = m_RampB[*(src_buf++)];
                *dest_buf++ = m_RampG[*(src_buf++)];
                *dest_buf++ = m_RampR[*(src_buf++)];
                if (!bSkip) {
                    *dest_buf++ = *src_buf;
                }
#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
                else {
                    dest_buf++;
                }
#endif
                src_buf ++;
            }
            break;
        default:
            break;
    }
}
void CPDF_DIBTransferFunc::TranslateDownSamples(uint8_t* dest_buf, const uint8_t* src_buf, int pixels, int Bpp) const
{
    if (Bpp == 8) {
        for (int i = 0; i < pixels; i ++) {
            *dest_buf++ = m_RampR[*(src_buf++)];
        }
    } else if (Bpp == 24) {
        for (int i = 0; i < pixels; i ++) {
            *dest_buf++ = m_RampB[*(src_buf++)];
            *dest_buf++ = m_RampG[*(src_buf++)];
            *dest_buf++ = m_RampR[*(src_buf++)];
        }
    } else {
#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
        if (!m_pSrc->HasAlpha()) {
            for (int i = 0; i < pixels; i ++) {
                *dest_buf++ = m_RampB[*(src_buf++)];
                *dest_buf++ = m_RampG[*(src_buf++)];
                *dest_buf++ = m_RampR[*(src_buf++)];
                dest_buf++;
                src_buf++;
            }
        } else
#endif
            for (int i = 0; i < pixels; i ++) {
                *dest_buf++ = m_RampB[*(src_buf++)];
                *dest_buf++ = m_RampG[*(src_buf++)];
                *dest_buf++ = m_RampR[*(src_buf++)];
                *dest_buf++ = *(src_buf++);
            }
    }
}
static bool _IsSupported(CPDF_ColorSpace* pCS)
{
    if (pCS->GetFamily() == PDFCS_DEVICERGB || pCS->GetFamily() == PDFCS_DEVICEGRAY ||
            pCS->GetFamily() == PDFCS_DEVICECMYK || pCS->GetFamily() == PDFCS_CALGRAY ||
            pCS->GetFamily() == PDFCS_CALRGB) {
        return true;
    }
    if (pCS->GetFamily() == PDFCS_INDEXED && _IsSupported(pCS->GetBaseCS())) {
        return true;
    }
    return false;
}
CPDF_ImageRenderer::CPDF_ImageRenderer()
{
    m_pRenderStatus = NULL;
    m_pImageObject = NULL;
    m_Result = true;
    m_Status = 0;
    m_pQuickStretcher = NULL;
    m_pTransformer = NULL;
    m_DeviceHandle = NULL;
    m_LoadHandle = NULL;
    m_pClone = NULL;
    m_bStdCS = false;
    m_bPatternColor = false;
    m_BlendType = FXDIB_BLEND_NORMAL;
    m_pPattern = NULL;
    m_pObj2Device = NULL;
}
CPDF_ImageRenderer::~CPDF_ImageRenderer()
{
    delete m_pQuickStretcher;
    delete m_pTransformer;
    if (m_DeviceHandle) {
        m_pRenderStatus->m_pDevice->CancelDIBits(m_DeviceHandle);
    }
    delete (CPDF_ProgressiveImageLoaderHandle*)m_LoadHandle;
    delete m_pClone;
}
bool CPDF_ImageRenderer::StartLoadDIBSource()
{
    CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
    FX_RECT image_rect = image_rect_f.GetOutterRect();
    int dest_width = image_rect.Width();
    int dest_height = image_rect.Height();
    if (m_ImageMatrix.a < 0) {
        dest_width = -dest_width;
    }
    if (m_ImageMatrix.d > 0) {
        dest_height = -dest_height;
    }
    if (m_Loader.StartLoadImage(m_pImageObject, m_pRenderStatus->m_pContext->m_pPageCache, m_LoadHandle, m_bStdCS,
                                m_pRenderStatus->m_GroupFamily, m_pRenderStatus->m_bLoadMask, m_pRenderStatus, dest_width, dest_height)) {
        if (m_LoadHandle != NULL) {
            m_Status = 4;
            return true;
        }
        return false;
    }
    return false;
}
bool CPDF_ImageRenderer::StartRenderDIBSource()
{
    if (m_Loader.m_pBitmap == NULL) {
        return false;
    }
    m_BitmapAlpha = 255;
    const CPDF_GeneralStateData* pGeneralState = m_pImageObject->m_GeneralState;
    if (pGeneralState) {
        m_BitmapAlpha = FXSYS_round(pGeneralState->m_FillAlpha * 255);
    }
    m_pDIBSource = m_Loader.m_pBitmap;
    if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_ALPHA && m_Loader.m_pMask == NULL) {
        return StartBitmapAlpha();
    }
    if (pGeneralState && pGeneralState->m_pTR) {
        if (!pGeneralState->m_pTransferFunc) {
            ((CPDF_GeneralStateData*)pGeneralState)->m_pTransferFunc = m_pRenderStatus->GetTransferFunc(pGeneralState->m_pTR);
        }
        if (pGeneralState->m_pTransferFunc && !pGeneralState->m_pTransferFunc->m_bIdentity) {
            m_pDIBSource = m_Loader.m_pBitmap = pGeneralState->m_pTransferFunc->TranslateImage(m_Loader.m_pBitmap, !m_Loader.m_bCached);
            if (m_Loader.m_bCached && m_Loader.m_pMask) {
                m_Loader.m_pMask = m_Loader.m_pMask->Clone();
            }
            m_Loader.m_bCached = false;
        }
    }
    m_FillArgb = 0;
    m_bPatternColor = false;
    m_pPattern = NULL;
    if (m_pDIBSource->IsAlphaMask()) {
        CPDF_Color* pColor = m_pImageObject->m_ColorState.GetFillColor();
        if (pColor && pColor->IsPattern()) {
            m_pPattern = pColor->GetPattern();
            if (m_pPattern != NULL) {
                m_bPatternColor = true;
            }
        }
        m_FillArgb = m_pRenderStatus->GetFillArgb(m_pImageObject);
    } else if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
        m_pClone = m_pDIBSource->Clone();
        m_pClone->ConvertColorScale(m_pRenderStatus->m_Options.m_BackColor, m_pRenderStatus->m_Options.m_ForeColor);
        m_pDIBSource = m_pClone;
    }
    m_Flags = 0;
    if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_DOWNSAMPLE) {
        m_Flags |= RENDER_FORCE_DOWNSAMPLE;
    } else if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_HALFTONE) {
        m_Flags |= RENDER_FORCE_HALFTONE;
    }
    if (m_pRenderStatus->m_pDevice->GetDeviceClass() != FXDC_DISPLAY) {
        CPDF_Object* pFilters = m_pImageObject->m_pImage->GetStream()->GetDict()->GetElementValue(FX_BSTRC("Filter"));
        if (pFilters) {
            if (pFilters->GetType() == PDFOBJ_NAME) {
                CFX_ByteStringC bsDecodeType = pFilters->GetConstString();
                if (bsDecodeType == FX_BSTRC("DCTDecode") || bsDecodeType == FX_BSTRC("JPXDecode")) {
                    m_Flags |= FXRENDER_IMAGE_LOSSY;
                }
            } else if (pFilters->GetType() == PDFOBJ_ARRAY) {
                CPDF_Array* pArray = (CPDF_Array*)pFilters;
                for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
                    CFX_ByteStringC bsDecodeType = pArray->GetConstString(i);
                    if (bsDecodeType == FX_BSTRC("DCTDecode") || bsDecodeType == FX_BSTRC("JPXDecode")) {
                        m_Flags |= FXRENDER_IMAGE_LOSSY;
                        break;
                    }
                }
            }
        }
    }
    if (m_pRenderStatus->m_Options.m_Flags & RENDER_NOIMAGESMOOTH) {
        m_Flags |= FXDIB_NOSMOOTH;
    } else if (m_pImageObject->m_pImage->IsInterpol()) {
        m_Flags |= FXDIB_INTERPOL;
    }
    if (m_Loader.m_pMask) {
        return DrawMaskedImage();
    }
    if (m_bPatternColor) {
        return DrawPatternImage(m_pObj2Device);
    }
    if (m_BitmapAlpha == 255 && pGeneralState && pGeneralState->m_FillOP &&
            pGeneralState->m_OPMode == 0 && pGeneralState->m_BlendType == FXDIB_BLEND_NORMAL && pGeneralState->m_StrokeAlpha == 1 && pGeneralState->m_FillAlpha == 1) {
        CPDF_Document* pDocument = NULL;
        CPDF_Page* pPage = NULL;
        if (m_pRenderStatus->m_pContext->m_pPageCache) {
            pPage = m_pRenderStatus->m_pContext->m_pPageCache->GetPage();
            pDocument = pPage->m_pDocument;
        } else {
            pDocument = m_pImageObject->m_pImage->GetDocument();
        }
        CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL;
        CPDF_Object* pCSObj = m_pImageObject->m_pImage->GetStream()->GetDict()->GetElementValue(FX_BSTRC("ColorSpace"));
        CPDF_ColorSpace* pColorSpace = pDocument->LoadColorSpace(pCSObj, pPageResources);
        if (pColorSpace) {
            int format = pColorSpace->GetFamily();
            if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION || format == PDFCS_DEVICEN) {
                m_BlendType = FXDIB_BLEND_DARKEN;
            }
            pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
        }
    }
    return StartDIBSource();
}
bool CPDF_ImageRenderer::Start(CPDF_RenderStatus* pStatus, const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, bool bStdCS, int blendType)
{
    m_pRenderStatus = pStatus;
    m_bStdCS = bStdCS;
    m_pImageObject = (CPDF_ImageObject*)pObj;
    m_BlendType = blendType;
    m_pObj2Device = pObj2Device;
    CPDF_Dictionary* pOC = m_pImageObject->m_pImage->GetOC();
    if (pOC && m_pRenderStatus->m_Options.m_pOCContext && !m_pRenderStatus->m_Options.m_pOCContext->CheckOCGVisible(pOC)) {
        return false;
    }
    m_ImageMatrix = m_pImageObject->m_Matrix;
    m_ImageMatrix.Concat(*pObj2Device);
    if (StartLoadDIBSource()) {
        return true;
    }
    return StartRenderDIBSource();
}
bool CPDF_ImageRenderer::Start(CPDF_RenderStatus* pStatus, const CFX_DIBSource* pDIBSource, FX_ARGB bitmap_argb,
                                  int bitmap_alpha, const CFX_AffineMatrix* pImage2Device, FX_DWORD flags, bool bStdCS, int blendType)
{
    m_pRenderStatus = pStatus;
    m_pDIBSource = pDIBSource;
    m_FillArgb = bitmap_argb;
    m_BitmapAlpha = bitmap_alpha;
    m_ImageMatrix = *pImage2Device;
    m_Flags = flags;
    m_bStdCS = bStdCS;
    m_BlendType = blendType;
    return StartDIBSource();
}
bool	CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device)
{
    if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
        m_Result = false;
        return false;
    }
    FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOutterRect();
    rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox());
    if (rect.IsEmpty()) {
        return false;
    }
    CFX_AffineMatrix new_matrix = m_ImageMatrix;
    new_matrix.TranslateI(-rect.left, -rect.top);
    int width = rect.Width();
    int height = rect.Height();
    CFX_FxgeDevice bitmap_device1;
    if (!bitmap_device1.Create(rect.Width(), rect.Height(), FXDIB_Rgb32)) {
        return true;
    }
    bitmap_device1.GetBitmap()->Clear(0xffffff);
    {
        CPDF_RenderStatus bitmap_render;
        bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1, NULL, NULL,
                                 NULL, NULL, &m_pRenderStatus->m_Options, 0, m_pRenderStatus->m_bDropObjects, NULL, true);
        CFX_Matrix patternDevice = *pObj2Device;
        patternDevice.Translate((FX_FLOAT) - rect.left, (FX_FLOAT) - rect.top);
        if(m_pPattern->m_PatternType == PATTERN_TILING) {
            bitmap_render.DrawTilingPattern((CPDF_TilingPattern*)m_pPattern, m_pImageObject, &patternDevice, false);
        } else {
            bitmap_render.DrawShadingPattern((CPDF_ShadingPattern*)m_pPattern, m_pImageObject, &patternDevice, false);
        }
    }
    {
        CFX_FxgeDevice bitmap_device2;
        if (!bitmap_device2.Create(rect.Width(), rect.Height(), FXDIB_8bppRgb)) {
            return true;
        }
        bitmap_device2.GetBitmap()->Clear(0);
        CPDF_RenderStatus bitmap_render;
        bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2, NULL, NULL,
                                 NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, true);
        CPDF_ImageRenderer image_render;
        if (image_render.Start(&bitmap_render, m_pDIBSource, 0xffffffff, 255, &new_matrix, m_Flags, true)) {
            image_render.Continue(NULL);
        }
        if (m_Loader.m_MatteColor != 0xffffffff) {
            int matte_r = FXARGB_R(m_Loader.m_MatteColor);
            int matte_g = FXARGB_G(m_Loader.m_MatteColor);
            int matte_b = FXARGB_B(m_Loader.m_MatteColor);
            for (int row = 0; row < height; row ++) {
                uint8_t* dest_scan = (uint8_t*)bitmap_device1.GetBitmap()->GetScanline(row);
                const uint8_t* mask_scan = bitmap_device2.GetBitmap()->GetScanline(row);
                for (int col = 0; col < width; col ++) {
                    int alpha = *mask_scan ++;
                    if (alpha) {
                        int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b;
                        if (orig < 0) {
                            orig = 0;
                        } else if (orig > 255) {
                            orig = 255;
                        }
                        *dest_scan++ = orig;
                        orig = (*dest_scan - matte_g) * 255 / alpha + matte_g;
                        if (orig < 0) {
                            orig = 0;
                        } else if (orig > 255) {
                            orig = 255;
                        }
                        *dest_scan++ = orig;
                        orig = (*dest_scan - matte_r) * 255 / alpha + matte_r;
                        if (orig < 0) {
                            orig = 0;
                        } else if (orig > 255) {
                            orig = 255;
                        }
                        *dest_scan++ = orig;
                        dest_scan ++;
                    } else {
                        dest_scan += 4;
                    }
                }
            }
        }
        bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask);
        bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap());
        bitmap_device1.GetBitmap()->MultiplyAlpha(255);
    }
    m_pRenderStatus->m_pDevice->SetDIBits(bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType);
    return false;
}
bool CPDF_ImageRenderer::DrawMaskedImage()
{
    if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
        m_Result = false;
        return false;
    }
    FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOutterRect();
    rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox());
    if (rect.IsEmpty()) {
        return false;
    }
    CFX_AffineMatrix new_matrix = m_ImageMatrix;
    new_matrix.TranslateI(-rect.left, -rect.top);
    int width = rect.Width();
    int height = rect.Height();
    CFX_FxgeDevice bitmap_device1;
    if (!bitmap_device1.Create(width, height, FXDIB_Rgb32)) {
        return true;
    }
    bitmap_device1.GetBitmap()->Clear(0xffffff);
    {
        CPDF_RenderStatus bitmap_render;
        bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1, NULL, NULL,
                                 NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, true);
        CPDF_ImageRenderer image_render;
        if (image_render.Start(&bitmap_render, m_pDIBSource, 0, 255, &new_matrix, m_Flags, true)) {
            image_render.Continue(NULL);
        }
    }
    {
        CFX_FxgeDevice bitmap_device2;
        if (!bitmap_device2.Create(width, height, FXDIB_8bppRgb)) {
            return true;
        }
        bitmap_device2.GetBitmap()->Clear(0);
        CPDF_RenderStatus bitmap_render;
        bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2, NULL, NULL,
                                 NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, true);
        CPDF_ImageRenderer image_render;
        if (image_render.Start(&bitmap_render, m_Loader.m_pMask, 0xffffffff, 255, &new_matrix, m_Flags, true)) {
            image_render.Continue(NULL);
        }
        if (m_Loader.m_MatteColor != 0xffffffff) {
            int matte_r = FXARGB_R(m_Loader.m_MatteColor);
            int matte_g = FXARGB_G(m_Loader.m_MatteColor);
            int matte_b = FXARGB_B(m_Loader.m_MatteColor);
            for (int row = 0; row < height; row ++) {
                uint8_t* dest_scan = (uint8_t*)bitmap_device1.GetBitmap()->GetScanline(row);
                const uint8_t* mask_scan = bitmap_device2.GetBitmap()->GetScanline(row);
                for (int col = 0; col < width; col ++) {
                    int alpha = *mask_scan ++;
                    if (alpha) {
                        int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b;
                        if (orig < 0) {
                            orig = 0;
                        } else if (orig > 255) {
                            orig = 255;
                        }
                        *dest_scan++ = orig;
                        orig = (*dest_scan - matte_g) * 255 / alpha + matte_g;
                        if (orig < 0) {
                            orig = 0;
                        } else if (orig > 255) {
                            orig = 255;
                        }
                        *dest_scan++ = orig;
                        orig = (*dest_scan - matte_r) * 255 / alpha + matte_r;
                        if (orig < 0) {
                            orig = 0;
                        } else if (orig > 255) {
                            orig = 255;
                        }
                        *dest_scan++ = orig;
                        dest_scan ++;
                    } else {
                        dest_scan += 4;
                    }
                }
            }
        }
        bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask);
        bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap());
        if (m_BitmapAlpha < 255) {
            bitmap_device1.GetBitmap()->MultiplyAlpha(m_BitmapAlpha);
        }
    }
    m_pRenderStatus->m_pDevice->SetDIBits(bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType);
    return false;
}
bool CPDF_ImageRenderer::StartDIBSource()
{
    if (!(m_Flags & RENDER_FORCE_DOWNSAMPLE) && m_pDIBSource->GetBPP() > 1) {
        int image_size = m_pDIBSource->GetBPP() / 8 * m_pDIBSource->GetWidth() * m_pDIBSource->GetHeight();
        if (image_size > FPDF_HUGE_IMAGE_SIZE && !(m_Flags & RENDER_FORCE_HALFTONE)) {
            m_Flags |= RENDER_FORCE_DOWNSAMPLE;
        }
    }
    if (m_pRenderStatus->m_pDevice->StartDIBits(m_pDIBSource, m_BitmapAlpha, m_FillArgb,
            &m_ImageMatrix, m_Flags, m_DeviceHandle, 0, NULL, m_BlendType)) {
        if (m_DeviceHandle != NULL) {
            m_Status = 3;
            return true;
        }
        return false;
    }
    CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
    FX_RECT image_rect = image_rect_f.GetOutterRect();
    int dest_width = image_rect.Width();
    int dest_height = image_rect.Height();
    if ((FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) ||
            (FXSYS_fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0) ) {
        if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
            m_Result = false;
            return false;
        }
        FX_RECT clip_box = m_pRenderStatus->m_pDevice->GetClipBox();
        clip_box.Intersect(image_rect);
        m_Status = 2;
        m_pTransformer = new CFX_ImageTransformer;
        m_pTransformer->Start(m_pDIBSource, &m_ImageMatrix, m_Flags, &clip_box);
        return true;
    }
    if (m_ImageMatrix.a < 0) {
        dest_width = -dest_width;
    }
    if (m_ImageMatrix.d > 0) {
        dest_height = -dest_height;
    }
    int dest_left, dest_top;
    dest_left = dest_width > 0 ? image_rect.left : image_rect.right;
    dest_top = dest_height > 0 ? image_rect.top : image_rect.bottom;
    if (m_pDIBSource->IsOpaqueImage() && m_BitmapAlpha == 255) {
        if (m_pRenderStatus->m_pDevice->StretchDIBits(m_pDIBSource, dest_left, dest_top,
                dest_width, dest_height, m_Flags, NULL, m_BlendType)) {
            return false;
        }
    }
    if (m_pDIBSource->IsAlphaMask()) {
        if (m_BitmapAlpha != 255) {
            m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
        }
        if (m_pRenderStatus->m_pDevice->StretchBitMask(m_pDIBSource, dest_left, dest_top, dest_width, dest_height, m_FillArgb, m_Flags)) {
            return false;
        }
    }
    if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
        m_Result = false;
        return true;
    }
    FX_RECT clip_box = m_pRenderStatus->m_pDevice->GetClipBox();
    FX_RECT dest_rect = clip_box;
    dest_rect.Intersect(image_rect);
    FX_RECT dest_clip(dest_rect.left - image_rect.left, dest_rect.top - image_rect.top,
                      dest_rect.right - image_rect.left, dest_rect.bottom - image_rect.top);
    CFX_DIBitmap* pStretched = m_pDIBSource->StretchTo(dest_width, dest_height, m_Flags, &dest_clip);
    if (pStretched) {
        m_pRenderStatus->CompositeDIBitmap(pStretched, dest_rect.left, dest_rect.top, m_FillArgb,
                                           m_BitmapAlpha, m_BlendType, false);
        delete pStretched;
        pStretched = NULL;
    }
    return false;
}
bool CPDF_ImageRenderer::StartBitmapAlpha()
{
    if (m_pDIBSource->IsOpaqueImage()) {
        CFX_PathData path;
        path.AppendRect(0, 0, 1, 1);
        path.Transform(&m_ImageMatrix);
        FX_DWORD fill_color = ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha);
        m_pRenderStatus->m_pDevice->DrawPath(&path, NULL, NULL, fill_color, 0, FXFILL_WINDING);
    } else {
        const CFX_DIBSource* pAlphaMask = m_pDIBSource->IsAlphaMask() ? m_pDIBSource : m_pDIBSource->GetAlphaMask();
        if (FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || FXSYS_fabs(m_ImageMatrix.c) >= 0.5f) {
            int left, top;
            CFX_DIBitmap* pTransformed = pAlphaMask->TransformTo(&m_ImageMatrix, left, top);
            if (pTransformed == NULL) {
                return true;
            }
            m_pRenderStatus->m_pDevice->SetBitMask(pTransformed, left, top, ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha));
            delete pTransformed;
        } else {
            CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
            FX_RECT image_rect = image_rect_f.GetOutterRect();
            int dest_width = m_ImageMatrix.a > 0 ? image_rect.Width() : -image_rect.Width();
            int dest_height = m_ImageMatrix.d > 0 ? -image_rect.Height() : image_rect.Height();
            int left = dest_width > 0 ? image_rect.left : image_rect.right;
            int top = dest_height > 0 ? image_rect.top : image_rect.bottom;
            m_pRenderStatus->m_pDevice->StretchBitMask(pAlphaMask, left, top, dest_width, dest_height,
                    ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha));
        }
        if (m_pDIBSource != pAlphaMask) {
            delete pAlphaMask;
        }
    }
    return false;
}
bool CPDF_ImageRenderer::Continue(IFX_Pause* pPause)
{
    if (m_Status == 1) {
        if (m_pQuickStretcher->Continue(pPause)) {
            return true;
        }
        if (m_pQuickStretcher->m_pBitmap->IsAlphaMask())
            m_pRenderStatus->m_pDevice->SetBitMask(m_pQuickStretcher->m_pBitmap, m_pQuickStretcher->m_ResultLeft,
                                                   m_pQuickStretcher->m_ResultTop, m_FillArgb);
        else
            m_pRenderStatus->m_pDevice->SetDIBits(m_pQuickStretcher->m_pBitmap, m_pQuickStretcher->m_ResultLeft,
                                                  m_pQuickStretcher->m_ResultTop, m_BlendType);
        return false;
    }
    if (m_Status == 2) {
        if (m_pTransformer->Continue(pPause)) {
            return true;
        }
        CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach();
        if (pBitmap == NULL) {
            return false;
        }
        if (pBitmap->IsAlphaMask()) {
            if (m_BitmapAlpha != 255) {
                m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
            }
            m_Result = m_pRenderStatus->m_pDevice->SetBitMask(pBitmap,
                       m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, m_FillArgb);
        } else {
            if (m_BitmapAlpha != 255) {
                pBitmap->MultiplyAlpha(m_BitmapAlpha);
            }
            m_Result = m_pRenderStatus->m_pDevice->SetDIBits(pBitmap,
                       m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, m_BlendType);
        }
        delete pBitmap;
        return false;
    }
    if (m_Status == 3) {
        return m_pRenderStatus->m_pDevice->ContinueDIBits(m_DeviceHandle, pPause);
    }
    if (m_Status == 4) {
        if (m_Loader.Continue(m_LoadHandle, pPause)) {
            return true;
        }
        if (StartRenderDIBSource()) {
            return Continue(pPause);
        }
    }
    return false;
}
CPDF_QuickStretcher::CPDF_QuickStretcher()
{
    m_pBitmap = NULL;
    m_pDecoder = NULL;
    m_pCS = NULL;
}
CPDF_QuickStretcher::~CPDF_QuickStretcher()
{
    delete m_pBitmap;
    if (m_pCS) {
        m_pCS->ReleaseCS();
    }
    delete m_pDecoder;
}
ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(const uint8_t* src_buf, FX_DWORD src_size, int width, int height,
        int nComps, int bpc, const CPDF_Dictionary* pParams);
bool CPDF_QuickStretcher::Start(CPDF_ImageObject* pImageObj, CFX_AffineMatrix* pImage2Device, const FX_RECT* pClipBox)
{
    if (FXSYS_fabs(pImage2Device->a) < FXSYS_fabs(pImage2Device->b) * 10 && FXSYS_fabs(pImage2Device->d) < FXSYS_fabs(pImage2Device->c) * 10) {
        return false;
    }
    CFX_FloatRect image_rect_f = pImage2Device->GetUnitRect();
    FX_RECT image_rect = image_rect_f.GetOutterRect();
    m_DestWidth = image_rect.Width();
    m_DestHeight = image_rect.Height();
    m_bFlipX = pImage2Device->a < 0;
    m_bFlipY = pImage2Device->d > 0;
    FX_RECT result_rect = *pClipBox;
    result_rect.Intersect(image_rect);
    if (result_rect.IsEmpty()) {
        return false;
    }
    m_ResultWidth = result_rect.Width();
    m_ResultHeight = result_rect.Height();
    m_ResultLeft = result_rect.left;
    m_ResultTop = result_rect.top;
    m_ClipLeft = result_rect.left - image_rect.left;
    m_ClipTop = result_rect.top - image_rect.top;
    CPDF_Dictionary* pDict = pImageObj->m_pImage->GetDict();
    if (pDict->GetInteger(FX_BSTRC("BitsPerComponent")) != 8) {
        return false;
    }
    if (pDict->KeyExist(FX_BSTRC("SMask")) || pDict->KeyExist(FX_BSTRC("Mask"))) {
        return false;
    }
    m_SrcWidth = pDict->GetInteger(FX_BSTRC("Width"));
    m_SrcHeight = pDict->GetInteger(FX_BSTRC("Height"));
    m_pCS = NULL;
    m_Bpp = 3;
    CPDF_Object* pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace"));
    if (pCSObj == NULL) {
        return false;
    }
    m_pCS = CPDF_ColorSpace::Load(pImageObj->m_pImage->GetDocument(), pCSObj);
    if (m_pCS == NULL) {
        return false;
    }
    if (!_IsSupported(m_pCS)) {
        return false;
    }
    m_Bpp = m_pCS->CountComponents();
    if (m_pCS->sRGB()) {
        m_pCS->ReleaseCS();
        m_pCS = NULL;
    }
    CPDF_Stream* pStream = pImageObj->m_pImage->GetStream();
    m_StreamAcc.LoadAllData(pStream, false, m_SrcWidth * m_SrcHeight * m_Bpp, true);
    m_pDecoder = NULL;
    if (!m_StreamAcc.GetImageDecoder().IsEmpty()) {
        if (m_StreamAcc.GetImageDecoder() == FX_BSTRC("DCTDecode")) {
            const CPDF_Dictionary* pParam = m_StreamAcc.GetImageParam();
            m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder(
                             m_StreamAcc.GetData(), m_StreamAcc.GetSize(), m_SrcWidth, m_SrcHeight, m_Bpp,
                             pParam ? pParam->GetInteger(FX_BSTRC("ColorTransform"), 1) : 1);
        } else if (m_StreamAcc.GetImageDecoder() == FX_BSTRC("FlateDecode")) {
            m_pDecoder = FPDFAPI_CreateFlateDecoder(
                             m_StreamAcc.GetData(), m_StreamAcc.GetSize(), m_SrcWidth, m_SrcHeight, m_Bpp, 8,
                             m_StreamAcc.GetImageParam());
        } else {
            return false;
        }
        m_pDecoder->DownScale(m_DestWidth, m_DestHeight);
    }
    m_pBitmap = new CFX_DIBitmap;
#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
    m_pBitmap->Create(m_ResultWidth, m_ResultHeight, FXDIB_Rgb32);
#else
    m_pBitmap->Create(m_ResultWidth, m_ResultHeight, FXDIB_Rgb);
#endif
    m_LineIndex = 0;
    return true;
}
bool CPDF_QuickStretcher::Continue(IFX_Pause* pPause)
{
    uint8_t* result_buf = m_pBitmap->GetBuffer();
    int src_width = m_pDecoder ? m_pDecoder->GetWidth() : m_SrcWidth;
    int src_height = m_pDecoder ? m_pDecoder->GetHeight() : m_SrcHeight;
    int src_pitch = src_width * m_Bpp;
    while (m_LineIndex < m_ResultHeight) {
        int dest_y, src_y;
        if (m_bFlipY) {
            dest_y = m_ResultHeight - m_LineIndex - 1;
            src_y = (m_DestHeight - (dest_y + m_ClipTop) - 1) * src_height / m_DestHeight;
        } else {
            dest_y = m_LineIndex;
            src_y = (dest_y + m_ClipTop) * src_height / m_DestHeight;
        }
        const uint8_t* src_scan;
        if (m_pDecoder) {
            src_scan = m_pDecoder->GetScanline(src_y);
            if (src_scan == NULL) {
                break;
            }
        } else {
            src_scan = m_StreamAcc.GetData();
            if (src_scan == NULL) {
                break;
            }
            src_scan += src_y * src_pitch;
        }
        uint8_t* result_scan = result_buf + dest_y * m_pBitmap->GetPitch();
        for (int x = 0; x < m_ResultWidth; x ++) {
            int dest_x = m_ClipLeft + x;
            int src_x = (m_bFlipX ? (m_DestWidth - dest_x - 1) : dest_x) * src_width / m_DestWidth;
            const uint8_t* src_pixel = src_scan + src_x * m_Bpp;
            if (m_pCS == NULL) {
                *result_scan = src_pixel[2];
                result_scan ++;
                *result_scan = src_pixel[1];
                result_scan ++;
                *result_scan = src_pixel[0];
                result_scan ++;
#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
                result_scan ++;
#endif
            } else {
                m_pCS->TranslateImageLine(result_scan, src_pixel, 1, 0, 0);
#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
                result_scan += 4;
#else
                result_scan += 3;
#endif
            }
        }
        m_LineIndex ++;
        if (pPause && pPause->NeedToPauseNow()) {
            return true;
        }
    }
    return false;
}
CFX_DIBitmap* CPDF_RenderStatus::LoadSMask(CPDF_Dictionary* pSMaskDict,
        FX_RECT* pClipRect, const CFX_AffineMatrix* pMatrix)
{
    if (pSMaskDict == NULL) {
        return NULL;
    }
    CFX_DIBitmap* pMask = NULL;
    int width = pClipRect->right - pClipRect->left;
    int height = pClipRect->bottom - pClipRect->top;
    bool bLuminosity = false;
    bLuminosity = pSMaskDict->GetConstString(FX_BSTRC("S")) != FX_BSTRC("Alpha");
    CPDF_Stream* pGroup = pSMaskDict->GetStream(FX_BSTRC("G"));
    if (pGroup == NULL) {
        return NULL;
    }
    CPDF_Function* pFunc = NULL;
    CPDF_Object* pFuncObj = pSMaskDict->GetElementValue(FX_BSTRC("TR"));
    if (pFuncObj && (pFuncObj->GetType() == PDFOBJ_DICTIONARY || pFuncObj->GetType() == PDFOBJ_STREAM)) {
        pFunc = CPDF_Function::Load(pFuncObj);
    }
    CFX_AffineMatrix matrix = *pMatrix;
    matrix.TranslateI(-pClipRect->left, -pClipRect->top);
    CPDF_Form form(m_pContext->m_pDocument, m_pContext->m_pPageResources, pGroup);
    form.ParseContent(NULL, NULL, NULL, NULL);
    CFX_FxgeDevice bitmap_device;
#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
    if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb32 : FXDIB_8bppMask)) {
        return NULL;
    }
#else
    if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb : FXDIB_8bppMask)) {
        return NULL;
    }
#endif
    CFX_DIBitmap& bitmap = *bitmap_device.GetBitmap();
    CPDF_Object* pCSObj = NULL;
    CPDF_ColorSpace* pCS = NULL;
    if (bLuminosity) {
        CPDF_Array* pBC = pSMaskDict->GetArray(FX_BSTRC("BC"));
        FX_ARGB back_color = 0xff000000;
        if (pBC) {
            CPDF_Dictionary* pDict = pGroup->GetDict();
            if (pDict && pDict->GetDict(FX_BSTRC("Group")))
                pCSObj = pDict->GetDict(FX_BSTRC("Group"))->GetElementValue(FX_BSTRC("CS"));
            else
                pCSObj = NULL;
            pCS = m_pContext->m_pDocument->LoadColorSpace(pCSObj);
            if (pCS) {
                FX_FLOAT R, G, B;
                FX_DWORD comps = 8;
                if (pCS->CountComponents() > static_cast<int32_t>(comps)) {
                    comps = (FX_DWORD)pCS->CountComponents();
                }
                CFX_FixedBufGrow<FX_FLOAT, 8> float_array(comps);
                FX_FLOAT* pFloats = float_array;
                FX_SAFE_DWORD num_floats = comps;
                num_floats *= sizeof(FX_FLOAT);
                if (!num_floats.IsValid()) {
                    return NULL;
                }
                FXSYS_memset(pFloats, 0, num_floats.ValueOrDie());
                int count = pBC->GetCount() > 8 ? 8 : pBC->GetCount();
                for (int i = 0; i < count; i ++) {
                    pFloats[i] = pBC->GetNumber(i);
                }
                pCS->GetRGB(pFloats, R, G, B);
                back_color = 0xff000000 | ((int32_t)(R * 255) << 16) | ((int32_t)(G * 255) << 8) | (int32_t)(B * 255);
                m_pContext->m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
            }
        }
        bitmap.Clear(back_color);
    } else {
        bitmap.Clear(0);
    }
    CPDF_Dictionary* pFormResource = NULL;
    if (form.m_pFormDict) {
        pFormResource = form.m_pFormDict->GetDict(FX_BSTRC("Resources"));
    }
    CPDF_RenderOptions options;
    options.m_ColorMode = bLuminosity ? RENDER_COLOR_NORMAL : RENDER_COLOR_ALPHA;
    CPDF_RenderStatus status;
    status.Initialize(m_pContext, &bitmap_device, NULL, NULL, NULL, NULL,
                      &options, 0, m_bDropObjects, pFormResource, true, NULL, 0, pCS ? pCS->GetFamily() : 0, bLuminosity);
    status.RenderObjectList(&form, &matrix);
    pMask = new CFX_DIBitmap;
    if (!pMask->Create(width, height, FXDIB_8bppMask)) {
        delete pMask;
        return NULL;
    }
    uint8_t* dest_buf = pMask->GetBuffer();
    int dest_pitch = pMask->GetPitch();
    uint8_t* src_buf = bitmap.GetBuffer();
    int src_pitch = bitmap.GetPitch();
    uint8_t* pTransfer = FX_Alloc(uint8_t, 256);
    if (pFunc) {
        CFX_FixedBufGrow<FX_FLOAT, 16> results(pFunc->CountOutputs());
        for (int i = 0; i < 256; i ++) {
            FX_FLOAT input = (FX_FLOAT)i / 255.0f;
            int nresult;
            pFunc->Call(&input, 1, results, nresult);
            pTransfer[i] = FXSYS_round(results[0] * 255);
        }
    } else {
        for (int i = 0; i < 256; i ++) {
            pTransfer[i] = i;
        }
    }
    if (bLuminosity) {
        int Bpp = bitmap.GetBPP() / 8;
        for (int row = 0; row < height; row ++) {
            uint8_t* dest_pos = dest_buf + row * dest_pitch;
            uint8_t* src_pos = src_buf + row * src_pitch;
            for (int col = 0; col < width; col ++) {
                *dest_pos ++ = pTransfer[FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos)];
                src_pos += Bpp;
            }
        }
    } else if (pFunc) {
        int size = dest_pitch * height;
        for (int i = 0; i < size; i ++) {
            dest_buf[i] = pTransfer[src_buf[i]];
        }
    } else {
        FXSYS_memcpy(dest_buf, src_buf, dest_pitch * height);
    }
    delete pFunc;
    FX_Free(pTransfer);
    return pMask;
}
