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 FX_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);
     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     if (src_buf == NULL) {
     57         return FALSE;
     58     }
     59     int ret = 0;
     60     if(!file_ptr->ReadBlock(src_buf, 0, src_size)) {
     61         goto failed;
     62     }
     63     pContext = CJBig2_Context::CreateContext(&m_Module, NULL, 0, src_buf, src_size, JBIG2_FILE_STREAM);
     64     if(pContext == NULL) {
     65         goto failed;
     66     }
     67     ret = pContext->getFirstPage(&dest_image, NULL);
     68     CJBig2_Context::DestroyContext(pContext);
     69     if (ret != JBIG2_SUCCESS) {
     70         goto failed;
     71     }
     72     width = (FX_DWORD)dest_image->m_nWidth;
     73     height = (FX_DWORD)dest_image->m_nHeight;
     74     pitch = (FX_DWORD)dest_image->m_nStride;
     75     dest_buf = dest_image->m_pData;
     76     dest_image->m_bNeedFree = FALSE;
     77     delete dest_image;
     78     FX_Free(src_buf);
     79     return TRUE;
     80 failed:
     81     if(src_buf) {
     82         FX_Free(src_buf);
     83     }
     84     return FALSE;
     85 }
     86 FXCODEC_STATUS CCodec_Jbig2Module::StartDecode(void* pJbig2Context, FX_DWORD width, FX_DWORD height, FX_LPCBYTE src_buf, FX_DWORD src_size,
     87         FX_LPCBYTE global_data, FX_DWORD global_size, FX_LPBYTE dest_buf, FX_DWORD dest_pitch, IFX_Pause* pPause)
     88 {
     89     if(!pJbig2Context) {
     90         return FXCODEC_STATUS_ERR_PARAMS;
     91     }
     92     CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
     93     m_pJbig2Context->m_width = width;
     94     m_pJbig2Context->m_height = height;
     95     m_pJbig2Context->m_src_buf = (unsigned char *)src_buf;
     96     m_pJbig2Context->m_src_size = src_size;
     97     m_pJbig2Context->m_global_data = global_data;
     98     m_pJbig2Context->m_global_size = global_size;
     99     m_pJbig2Context->m_dest_buf = dest_buf;
    100     m_pJbig2Context->m_dest_pitch = dest_pitch;
    101     m_pJbig2Context->m_pPause = pPause;
    102     m_pJbig2Context->m_bFileReader = FALSE;
    103     FXSYS_memset32(dest_buf, 0, height * dest_pitch);
    104     m_pJbig2Context->m_pContext = CJBig2_Context::CreateContext(&m_Module,
    105                                   (FX_LPBYTE)global_data, global_size, (FX_LPBYTE)src_buf, src_size, JBIG2_EMBED_STREAM, pPause);
    106     if(!m_pJbig2Context->m_pContext) {
    107         return FXCODEC_STATUS_ERROR;
    108     }
    109     int ret = m_pJbig2Context->m_pContext->getFirstPage(dest_buf, width, height, dest_pitch, pPause);
    110     if(m_pJbig2Context->m_pContext->GetProcessiveStatus() == FXCODEC_STATUS_DECODE_FINISH) {
    111         CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
    112         m_pJbig2Context->m_pContext = NULL;
    113         if (ret != JBIG2_SUCCESS) {
    114             return FXCODEC_STATUS_ERROR;
    115         }
    116         int dword_size = height * dest_pitch / 4;
    117         FX_DWORD* dword_buf = (FX_DWORD*)dest_buf;
    118         for (int i = 0; i < dword_size; i ++) {
    119             dword_buf[i] = ~dword_buf[i];
    120         }
    121         return FXCODEC_STATUS_DECODE_FINISH;
    122     }
    123     return m_pJbig2Context->m_pContext->GetProcessiveStatus();
    124 }
    125 FXCODEC_STATUS CCodec_Jbig2Module::StartDecode(void* pJbig2Context, IFX_FileRead* file_ptr,
    126         FX_DWORD& width, FX_DWORD& height, FX_DWORD& pitch, FX_LPBYTE& dest_buf, IFX_Pause* pPause)
    127 {
    128     if(!pJbig2Context) {
    129         return FXCODEC_STATUS_ERR_PARAMS;
    130     }
    131     CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
    132     m_pJbig2Context->m_bFileReader = TRUE;
    133     m_pJbig2Context->m_dest_image = NULL;
    134     m_pJbig2Context->m_src_size = (FX_DWORD)file_ptr->GetSize();
    135     m_pJbig2Context->m_src_buf = FX_Alloc(FX_BYTE, m_pJbig2Context->m_src_size);
    136     if (m_pJbig2Context->m_src_buf == NULL) {
    137         return FXCODEC_STATUS_ERR_MEMORY;
    138     }
    139     int ret = 0;
    140     if(!file_ptr->ReadBlock((void*)m_pJbig2Context->m_src_buf, 0, m_pJbig2Context->m_src_size)) {
    141         goto failed;
    142     }
    143     m_pJbig2Context->m_pContext = CJBig2_Context::CreateContext(&m_Module, NULL, 0, m_pJbig2Context->m_src_buf, m_pJbig2Context->m_src_size, JBIG2_FILE_STREAM, pPause);
    144     if(m_pJbig2Context->m_pContext == NULL) {
    145         goto failed;
    146     }
    147     ret = m_pJbig2Context->m_pContext->getFirstPage(&m_pJbig2Context->m_dest_image, pPause);
    148     if(m_pJbig2Context->m_pContext->GetProcessiveStatus() == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
    149         width = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nWidth;
    150         height = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nHeight;
    151         pitch = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nStride;
    152         dest_buf = m_pJbig2Context->m_dest_image->m_pData;
    153         m_pJbig2Context->m_dest_image->m_bNeedFree = FALSE;
    154         return FXCODEC_STATUS_DECODE_TOBECONTINUE;
    155     }
    156     CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
    157     m_pJbig2Context->m_pContext = NULL;
    158     if (ret != JBIG2_SUCCESS) {
    159         goto failed;
    160     }
    161     width = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nWidth;
    162     height = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nHeight;
    163     pitch = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nStride;
    164     dest_buf = m_pJbig2Context->m_dest_image->m_pData;
    165     m_pJbig2Context->m_dest_image->m_bNeedFree = FALSE;
    166     delete m_pJbig2Context->m_dest_image;
    167     FX_Free(m_pJbig2Context->m_src_buf);
    168     return FXCODEC_STATUS_DECODE_FINISH;
    169 failed:
    170     if(m_pJbig2Context->m_src_buf) {
    171         FX_Free(m_pJbig2Context->m_src_buf);
    172     }
    173     m_pJbig2Context->m_src_buf = NULL;
    174     return FXCODEC_STATUS_ERROR;
    175 }
    176 FXCODEC_STATUS CCodec_Jbig2Module::ContinueDecode(void* pJbig2Context, IFX_Pause* pPause)
    177 {
    178     CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
    179     int ret = m_pJbig2Context->m_pContext->Continue(pPause);
    180     if(m_pJbig2Context->m_pContext->GetProcessiveStatus() == FXCODEC_STATUS_DECODE_FINISH) {
    181         if(m_pJbig2Context->m_bFileReader) {
    182             CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
    183             m_pJbig2Context->m_pContext = NULL;
    184             if (ret != JBIG2_SUCCESS) {
    185                 if(m_pJbig2Context->m_src_buf) {
    186                     FX_Free(m_pJbig2Context->m_src_buf);
    187                 }
    188                 m_pJbig2Context->m_src_buf = NULL;
    189                 return FXCODEC_STATUS_ERROR;
    190             }
    191             delete m_pJbig2Context->m_dest_image;
    192             FX_Free(m_pJbig2Context->m_src_buf);
    193             return FXCODEC_STATUS_DECODE_FINISH;
    194         } else {
    195             CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
    196             m_pJbig2Context->m_pContext = NULL;
    197             if (ret != JBIG2_SUCCESS) {
    198                 return FXCODEC_STATUS_ERROR;
    199             }
    200             int dword_size = m_pJbig2Context->m_height * m_pJbig2Context->m_dest_pitch / 4;
    201             FX_DWORD* dword_buf = (FX_DWORD*)m_pJbig2Context->m_dest_buf;
    202             for (int i = 0; i < dword_size; i ++) {
    203                 dword_buf[i] = ~dword_buf[i];
    204             }
    205             return FXCODEC_STATUS_DECODE_FINISH;
    206         }
    207     }
    208     return m_pJbig2Context->m_pContext->GetProcessiveStatus();
    209 }
    210 
    211 
    212 
    213