Home | History | Annotate | Download | only in codec
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "../../../include/fxcodec/fx_codec.h"
      8 #include "codec_int.h"
      9 CCodec_Jbig2Context::CCodec_Jbig2Context()
     10 {
     11     FXSYS_memset32(this, 0, sizeof(CCodec_Jbig2Context));
     12 }
     13 CCodec_Jbig2Module::~CCodec_Jbig2Module()
     14 {
     15 }
     16 void* CCodec_Jbig2Module::CreateJbig2Context()
     17 {
     18     return new CCodec_Jbig2Context();
     19 }
     20 void CCodec_Jbig2Module::DestroyJbig2Context(void* pJbig2Content)
     21 {
     22     if(pJbig2Content) {
     23         CJBig2_Context::DestroyContext(((CCodec_Jbig2Context*)pJbig2Content)->m_pContext);
     24         delete (CCodec_Jbig2Context*)pJbig2Content;
     25     }
     26     pJbig2Content = NULL;
     27 }
     28 FX_BOOL CCodec_Jbig2Module::Decode(FX_DWORD width, FX_DWORD height, FX_LPCBYTE src_buf, FX_DWORD src_size,
     29                                    FX_LPCBYTE global_data, FX_DWORD global_size, FX_LPBYTE dest_buf, FX_DWORD dest_pitch)
     30 {
     31     FXSYS_memset32(dest_buf, 0, height * dest_pitch);
     32     CJBig2_Context* pContext = CJBig2_Context::CreateContext(&m_Module,
     33                                (FX_LPBYTE)global_data, global_size, (FX_LPBYTE)src_buf, src_size, JBIG2_EMBED_STREAM, &m_SymbolDictCache);
     34     if (pContext == NULL) {
     35         return FALSE;
     36     }
     37     int ret = pContext->getFirstPage(dest_buf, width, height, dest_pitch, NULL);
     38     CJBig2_Context::DestroyContext(pContext);
     39     if (ret != JBIG2_SUCCESS) {
     40         return FALSE;
     41     }
     42     int dword_size = height * dest_pitch / 4;
     43     FX_DWORD* dword_buf = (FX_DWORD*)dest_buf;
     44     for (int i = 0; i < dword_size; i ++) {
     45         dword_buf[i] = ~dword_buf[i];
     46     }
     47     return TRUE;
     48 }
     49 FX_BOOL CCodec_Jbig2Module::Decode(IFX_FileRead* file_ptr,
     50                                    FX_DWORD& width, FX_DWORD& height, FX_DWORD& pitch, FX_LPBYTE& dest_buf)
     51 {
     52     CJBig2_Context* pContext = NULL;
     53     CJBig2_Image* dest_image = NULL;
     54     FX_DWORD src_size = (FX_DWORD)file_ptr->GetSize();
     55     FX_LPBYTE src_buf = FX_Alloc(FX_BYTE, src_size);
     56     int ret = 0;
     57     if(!file_ptr->ReadBlock(src_buf, 0, src_size)) {
     58         goto failed;
     59     }
     60     pContext = CJBig2_Context::CreateContext(&m_Module, NULL, 0, src_buf, src_size, JBIG2_FILE_STREAM, &m_SymbolDictCache);
     61     if(pContext == NULL) {
     62         goto failed;
     63     }
     64     ret = pContext->getFirstPage(&dest_image, NULL);
     65     CJBig2_Context::DestroyContext(pContext);
     66     if (ret != JBIG2_SUCCESS) {
     67         goto failed;
     68     }
     69     width = (FX_DWORD)dest_image->m_nWidth;
     70     height = (FX_DWORD)dest_image->m_nHeight;
     71     pitch = (FX_DWORD)dest_image->m_nStride;
     72     dest_buf = dest_image->m_pData;
     73     dest_image->m_bNeedFree = FALSE;
     74     delete dest_image;
     75     FX_Free(src_buf);
     76     return TRUE;
     77 failed:
     78     if(src_buf) {
     79         FX_Free(src_buf);
     80     }
     81     return FALSE;
     82 }
     83 FXCODEC_STATUS CCodec_Jbig2Module::StartDecode(void* pJbig2Context, FX_DWORD width, FX_DWORD height, FX_LPCBYTE src_buf, FX_DWORD src_size,
     84         FX_LPCBYTE global_data, FX_DWORD global_size, FX_LPBYTE dest_buf, FX_DWORD dest_pitch, IFX_Pause* pPause)
     85 {
     86     if(!pJbig2Context) {
     87         return FXCODEC_STATUS_ERR_PARAMS;
     88     }
     89     CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
     90     m_pJbig2Context->m_width = width;
     91     m_pJbig2Context->m_height = height;
     92     m_pJbig2Context->m_src_buf = (unsigned char *)src_buf;
     93     m_pJbig2Context->m_src_size = src_size;
     94     m_pJbig2Context->m_global_data = global_data;
     95     m_pJbig2Context->m_global_size = global_size;
     96     m_pJbig2Context->m_dest_buf = dest_buf;
     97     m_pJbig2Context->m_dest_pitch = dest_pitch;
     98     m_pJbig2Context->m_pPause = pPause;
     99     m_pJbig2Context->m_bFileReader = FALSE;
    100     FXSYS_memset32(dest_buf, 0, height * dest_pitch);
    101     m_pJbig2Context->m_pContext = CJBig2_Context::CreateContext(&m_Module,
    102                                   (FX_LPBYTE)global_data, global_size, (FX_LPBYTE)src_buf, src_size, JBIG2_EMBED_STREAM, &m_SymbolDictCache, pPause);
    103     if(!m_pJbig2Context->m_pContext) {
    104         return FXCODEC_STATUS_ERROR;
    105     }
    106     int ret = m_pJbig2Context->m_pContext->getFirstPage(dest_buf, width, height, dest_pitch, pPause);
    107     if(m_pJbig2Context->m_pContext->GetProcessiveStatus() == FXCODEC_STATUS_DECODE_FINISH) {
    108         CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
    109         m_pJbig2Context->m_pContext = NULL;
    110         if (ret != JBIG2_SUCCESS) {
    111             return FXCODEC_STATUS_ERROR;
    112         }
    113         int dword_size = height * dest_pitch / 4;
    114         FX_DWORD* dword_buf = (FX_DWORD*)dest_buf;
    115         for (int i = 0; i < dword_size; i ++) {
    116             dword_buf[i] = ~dword_buf[i];
    117         }
    118         return FXCODEC_STATUS_DECODE_FINISH;
    119     }
    120     return m_pJbig2Context->m_pContext->GetProcessiveStatus();
    121 }
    122 FXCODEC_STATUS CCodec_Jbig2Module::StartDecode(void* pJbig2Context, IFX_FileRead* file_ptr,
    123         FX_DWORD& width, FX_DWORD& height, FX_DWORD& pitch, FX_LPBYTE& dest_buf, IFX_Pause* pPause)
    124 {
    125     if(!pJbig2Context) {
    126         return FXCODEC_STATUS_ERR_PARAMS;
    127     }
    128     CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
    129     m_pJbig2Context->m_bFileReader = TRUE;
    130     m_pJbig2Context->m_dest_image = NULL;
    131     m_pJbig2Context->m_src_size = (FX_DWORD)file_ptr->GetSize();
    132     m_pJbig2Context->m_src_buf = FX_Alloc(FX_BYTE, m_pJbig2Context->m_src_size);
    133     int ret = 0;
    134     if(!file_ptr->ReadBlock((void*)m_pJbig2Context->m_src_buf, 0, m_pJbig2Context->m_src_size)) {
    135         goto failed;
    136     }
    137     m_pJbig2Context->m_pContext = CJBig2_Context::CreateContext(&m_Module, NULL, 0, m_pJbig2Context->m_src_buf, m_pJbig2Context->m_src_size, JBIG2_FILE_STREAM, &m_SymbolDictCache, pPause);
    138     if(m_pJbig2Context->m_pContext == NULL) {
    139         goto failed;
    140     }
    141     ret = m_pJbig2Context->m_pContext->getFirstPage(&m_pJbig2Context->m_dest_image, pPause);
    142     if(m_pJbig2Context->m_pContext->GetProcessiveStatus() == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
    143         width = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nWidth;
    144         height = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nHeight;
    145         pitch = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nStride;
    146         dest_buf = m_pJbig2Context->m_dest_image->m_pData;
    147         m_pJbig2Context->m_dest_image->m_bNeedFree = FALSE;
    148         return FXCODEC_STATUS_DECODE_TOBECONTINUE;
    149     }
    150     CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
    151     m_pJbig2Context->m_pContext = NULL;
    152     if (ret != JBIG2_SUCCESS) {
    153         goto failed;
    154     }
    155     width = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nWidth;
    156     height = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nHeight;
    157     pitch = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nStride;
    158     dest_buf = m_pJbig2Context->m_dest_image->m_pData;
    159     m_pJbig2Context->m_dest_image->m_bNeedFree = FALSE;
    160     delete m_pJbig2Context->m_dest_image;
    161     FX_Free(m_pJbig2Context->m_src_buf);
    162     return FXCODEC_STATUS_DECODE_FINISH;
    163 failed:
    164     if(m_pJbig2Context->m_src_buf) {
    165         FX_Free(m_pJbig2Context->m_src_buf);
    166     }
    167     m_pJbig2Context->m_src_buf = NULL;
    168     return FXCODEC_STATUS_ERROR;
    169 }
    170 FXCODEC_STATUS CCodec_Jbig2Module::ContinueDecode(void* pJbig2Context, IFX_Pause* pPause)
    171 {
    172     CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
    173     int ret = m_pJbig2Context->m_pContext->Continue(pPause);
    174     if(m_pJbig2Context->m_pContext->GetProcessiveStatus() == FXCODEC_STATUS_DECODE_FINISH) {
    175         if(m_pJbig2Context->m_bFileReader) {
    176             CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
    177             m_pJbig2Context->m_pContext = NULL;
    178             if (ret != JBIG2_SUCCESS) {
    179                 if(m_pJbig2Context->m_src_buf) {
    180                     FX_Free(m_pJbig2Context->m_src_buf);
    181                 }
    182                 m_pJbig2Context->m_src_buf = NULL;
    183                 return FXCODEC_STATUS_ERROR;
    184             }
    185             delete m_pJbig2Context->m_dest_image;
    186             FX_Free(m_pJbig2Context->m_src_buf);
    187             return FXCODEC_STATUS_DECODE_FINISH;
    188         } else {
    189             CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
    190             m_pJbig2Context->m_pContext = NULL;
    191             if (ret != JBIG2_SUCCESS) {
    192                 return FXCODEC_STATUS_ERROR;
    193             }
    194             int dword_size = m_pJbig2Context->m_height * m_pJbig2Context->m_dest_pitch / 4;
    195             FX_DWORD* dword_buf = (FX_DWORD*)m_pJbig2Context->m_dest_buf;
    196             for (int i = 0; i < dword_size; i ++) {
    197                 dword_buf[i] = ~dword_buf[i];
    198             }
    199             return FXCODEC_STATUS_DECODE_FINISH;
    200         }
    201     }
    202     return m_pJbig2Context->m_pContext->GetProcessiveStatus();
    203 }
    204 
    205 
    206 
    207