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 "core/fxcodec/codec/ccodec_bmpmodule.h"
      8 
      9 #include "core/fxcodec/codec/codec_int.h"
     10 #include "core/fxcodec/fx_codec.h"
     11 #include "core/fxcodec/lbmp/fx_bmp.h"
     12 #include "core/fxge/fx_dib.h"
     13 
     14 struct FXBMP_Context {
     15   bmp_decompress_struct_p bmp_ptr;
     16   void* parent_ptr;
     17 
     18   void* (*m_AllocFunc)(unsigned int);
     19   void (*m_FreeFunc)(void*);
     20 };
     21 extern "C" {
     22 static void* bmp_alloc_func(unsigned int size) {
     23   return FX_Alloc(char, size);
     24 }
     25 static void bmp_free_func(void* p) {
     26   FX_Free(p);
     27 }
     28 };
     29 static void bmp_error_data(bmp_decompress_struct_p bmp_ptr,
     30                            const FX_CHAR* err_msg) {
     31   FXSYS_strncpy((char*)bmp_ptr->err_ptr, err_msg, BMP_MAX_ERROR_SIZE - 1);
     32   longjmp(bmp_ptr->jmpbuf, 1);
     33 }
     34 static void bmp_read_scanline(bmp_decompress_struct_p bmp_ptr,
     35                               int32_t row_num,
     36                               uint8_t* row_buf) {
     37   FXBMP_Context* p = (FXBMP_Context*)bmp_ptr->context_ptr;
     38   CCodec_BmpModule* pModule = (CCodec_BmpModule*)p->parent_ptr;
     39   pModule->GetDelegate()->BmpReadScanline(row_num, row_buf);
     40 }
     41 static bool bmp_get_data_position(bmp_decompress_struct_p bmp_ptr,
     42                                   uint32_t rcd_pos) {
     43   FXBMP_Context* p = (FXBMP_Context*)bmp_ptr->context_ptr;
     44   CCodec_BmpModule* pModule = (CCodec_BmpModule*)p->parent_ptr;
     45   return pModule->GetDelegate()->BmpInputImagePositionBuf(rcd_pos);
     46 }
     47 
     48 CCodec_BmpModule::CCodec_BmpModule() {
     49   memset(m_szLastError, 0, sizeof(m_szLastError));
     50 }
     51 
     52 CCodec_BmpModule::~CCodec_BmpModule() {}
     53 
     54 FXBMP_Context* CCodec_BmpModule::Start() {
     55   FXBMP_Context* p = FX_Alloc(FXBMP_Context, 1);
     56   if (!p)
     57     return nullptr;
     58 
     59   FXSYS_memset(p, 0, sizeof(FXBMP_Context));
     60   if (!p)
     61     return nullptr;
     62 
     63   p->m_AllocFunc = bmp_alloc_func;
     64   p->m_FreeFunc = bmp_free_func;
     65   p->bmp_ptr = nullptr;
     66   p->parent_ptr = (void*)this;
     67   p->bmp_ptr = bmp_create_decompress();
     68   if (!p->bmp_ptr) {
     69     FX_Free(p);
     70     return nullptr;
     71   }
     72   p->bmp_ptr->context_ptr = (void*)p;
     73   p->bmp_ptr->err_ptr = m_szLastError;
     74   p->bmp_ptr->bmp_error_fn = bmp_error_data;
     75   p->bmp_ptr->bmp_get_row_fn = bmp_read_scanline;
     76   p->bmp_ptr->bmp_get_data_position_fn = bmp_get_data_position;
     77   return p;
     78 }
     79 
     80 void CCodec_BmpModule::Finish(FXBMP_Context* ctx) {
     81   if (ctx) {
     82     bmp_destroy_decompress(&ctx->bmp_ptr);
     83     ctx->m_FreeFunc(ctx);
     84   }
     85 }
     86 int32_t CCodec_BmpModule::ReadHeader(FXBMP_Context* ctx,
     87                                      int32_t* width,
     88                                      int32_t* height,
     89                                      bool* tb_flag,
     90                                      int32_t* components,
     91                                      int32_t* pal_num,
     92                                      uint32_t** pal_pp,
     93                                      CFX_DIBAttribute* pAttribute) {
     94   if (setjmp(ctx->bmp_ptr->jmpbuf)) {
     95     return 0;
     96   }
     97   int32_t ret = bmp_read_header(ctx->bmp_ptr);
     98   if (ret != 1) {
     99     return ret;
    100   }
    101   *width = ctx->bmp_ptr->width;
    102   *height = ctx->bmp_ptr->height;
    103   *tb_flag = ctx->bmp_ptr->imgTB_flag;
    104   *components = ctx->bmp_ptr->components;
    105   *pal_num = ctx->bmp_ptr->pal_num;
    106   *pal_pp = ctx->bmp_ptr->pal_ptr;
    107   if (pAttribute) {
    108     pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_METER;
    109     pAttribute->m_nXDPI = ctx->bmp_ptr->dpi_x;
    110     pAttribute->m_nYDPI = ctx->bmp_ptr->dpi_y;
    111     pAttribute->m_nBmpCompressType = ctx->bmp_ptr->compress_flag;
    112   }
    113   return 1;
    114 }
    115 
    116 int32_t CCodec_BmpModule::LoadImage(FXBMP_Context* ctx) {
    117   if (setjmp(ctx->bmp_ptr->jmpbuf))
    118     return 0;
    119   return bmp_decode_image(ctx->bmp_ptr);
    120 }
    121 
    122 uint32_t CCodec_BmpModule::GetAvailInput(FXBMP_Context* ctx,
    123                                          uint8_t** avail_buf_ptr) {
    124   return bmp_get_avail_input(ctx->bmp_ptr, avail_buf_ptr);
    125 }
    126 
    127 void CCodec_BmpModule::Input(FXBMP_Context* ctx,
    128                              const uint8_t* src_buf,
    129                              uint32_t src_size) {
    130   bmp_input_buffer(ctx->bmp_ptr, (uint8_t*)src_buf, src_size);
    131 }
    132