| OLD | NEW |
| (Empty) |
| 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/include/fxcodec/fx_codec.h" | |
| 8 #include "core/include/fxge/fx_dib.h" | |
| 9 #include "core/src/fxcodec/codec/fx_codec_progress.h" | |
| 10 void CFXCODEC_WeightTable::Calc(int dest_len, | |
| 11 int dest_min, | |
| 12 int dest_max, | |
| 13 int src_len, | |
| 14 int src_min, | |
| 15 int src_max, | |
| 16 FX_BOOL bInterpol) { | |
| 17 if (m_pWeightTables) { | |
| 18 FX_Free(m_pWeightTables); | |
| 19 } | |
| 20 double scale, base; | |
| 21 scale = (FX_FLOAT)src_len / (FX_FLOAT)dest_len; | |
| 22 if (dest_len < 0) { | |
| 23 base = (FX_FLOAT)(src_len); | |
| 24 } else { | |
| 25 base = 0.0f; | |
| 26 } | |
| 27 m_ItemSize = | |
| 28 (int)(sizeof(int) * 2 + | |
| 29 sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + 1)); | |
| 30 m_DestMin = dest_min; | |
| 31 m_pWeightTables = FX_Alloc(uint8_t, (dest_max - dest_min) * m_ItemSize + 4); | |
| 32 if (m_pWeightTables == NULL) { | |
| 33 return; | |
| 34 } | |
| 35 if (FXSYS_fabs((FX_FLOAT)scale) < 1.0f) { | |
| 36 for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { | |
| 37 PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); | |
| 38 double src_pos = dest_pixel * scale + scale / 2 + base; | |
| 39 if (bInterpol) { | |
| 40 pixel_weights.m_SrcStart = | |
| 41 (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); | |
| 42 pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); | |
| 43 if (pixel_weights.m_SrcStart < src_min) { | |
| 44 pixel_weights.m_SrcStart = src_min; | |
| 45 } | |
| 46 if (pixel_weights.m_SrcEnd >= src_max) { | |
| 47 pixel_weights.m_SrcEnd = src_max - 1; | |
| 48 } | |
| 49 if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { | |
| 50 pixel_weights.m_Weights[0] = 65536; | |
| 51 } else { | |
| 52 pixel_weights.m_Weights[1] = FXSYS_round( | |
| 53 (FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * | |
| 54 65536); | |
| 55 pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1]; | |
| 56 } | |
| 57 } else { | |
| 58 pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd = | |
| 59 (int)FXSYS_floor((FX_FLOAT)src_pos); | |
| 60 pixel_weights.m_Weights[0] = 65536; | |
| 61 } | |
| 62 } | |
| 63 return; | |
| 64 } | |
| 65 for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { | |
| 66 PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); | |
| 67 double src_start = dest_pixel * scale + base; | |
| 68 double src_end = src_start + scale; | |
| 69 int start_i, end_i; | |
| 70 if (src_start < src_end) { | |
| 71 start_i = (int)FXSYS_floor((FX_FLOAT)src_start); | |
| 72 end_i = (int)FXSYS_ceil((FX_FLOAT)src_end); | |
| 73 } else { | |
| 74 start_i = (int)FXSYS_floor((FX_FLOAT)src_end); | |
| 75 end_i = (int)FXSYS_ceil((FX_FLOAT)src_start); | |
| 76 } | |
| 77 if (start_i < src_min) { | |
| 78 start_i = src_min; | |
| 79 } | |
| 80 if (end_i >= src_max) { | |
| 81 end_i = src_max - 1; | |
| 82 } | |
| 83 if (start_i > end_i) { | |
| 84 pixel_weights.m_SrcStart = start_i; | |
| 85 pixel_weights.m_SrcEnd = start_i; | |
| 86 continue; | |
| 87 } | |
| 88 pixel_weights.m_SrcStart = start_i; | |
| 89 pixel_weights.m_SrcEnd = end_i; | |
| 90 for (int j = start_i; j <= end_i; j++) { | |
| 91 double dest_start = ((FX_FLOAT)j - base) / scale; | |
| 92 double dest_end = ((FX_FLOAT)(j + 1) - base) / scale; | |
| 93 if (dest_start > dest_end) { | |
| 94 double temp = dest_start; | |
| 95 dest_start = dest_end; | |
| 96 dest_end = temp; | |
| 97 } | |
| 98 double area_start = dest_start > (FX_FLOAT)(dest_pixel) | |
| 99 ? dest_start | |
| 100 : (FX_FLOAT)(dest_pixel); | |
| 101 double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) | |
| 102 ? (FX_FLOAT)(dest_pixel + 1) | |
| 103 : dest_end; | |
| 104 double weight = area_start >= area_end ? 0.0f : area_end - area_start; | |
| 105 if (weight == 0 && j == end_i) { | |
| 106 pixel_weights.m_SrcEnd--; | |
| 107 break; | |
| 108 } | |
| 109 pixel_weights.m_Weights[j - start_i] = | |
| 110 FXSYS_round((FX_FLOAT)(weight * 65536)); | |
| 111 } | |
| 112 } | |
| 113 } | |
| 114 void CFXCODEC_HorzTable::Calc(int dest_len, int src_len, FX_BOOL bInterpol) { | |
| 115 if (m_pWeightTables) { | |
| 116 FX_Free(m_pWeightTables); | |
| 117 } | |
| 118 double scale = (double)dest_len / (double)src_len; | |
| 119 m_ItemSize = sizeof(int) * 4; | |
| 120 int size = dest_len * m_ItemSize + 4; | |
| 121 m_pWeightTables = FX_Alloc(uint8_t, size); | |
| 122 if (m_pWeightTables == NULL) { | |
| 123 return; | |
| 124 } | |
| 125 FXSYS_memset(m_pWeightTables, 0, size); | |
| 126 if (scale > 1) { | |
| 127 int pre_des_col = 0; | |
| 128 for (int src_col = 0; src_col < src_len; src_col++) { | |
| 129 double des_col_f = src_col * scale; | |
| 130 int des_col = FXSYS_round((FX_FLOAT)des_col_f); | |
| 131 PixelWeight* pWeight = | |
| 132 (PixelWeight*)(m_pWeightTables + des_col * m_ItemSize); | |
| 133 pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col; | |
| 134 pWeight->m_Weights[0] = 65536; | |
| 135 pWeight->m_Weights[1] = 0; | |
| 136 if (src_col == src_len - 1 && des_col < dest_len - 1) { | |
| 137 for (int des_col_index = pre_des_col + 1; des_col_index < dest_len; | |
| 138 des_col_index++) { | |
| 139 pWeight = | |
| 140 (PixelWeight*)(m_pWeightTables + des_col_index * m_ItemSize); | |
| 141 pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col; | |
| 142 pWeight->m_Weights[0] = 65536; | |
| 143 pWeight->m_Weights[1] = 0; | |
| 144 } | |
| 145 return; | |
| 146 } | |
| 147 int des_col_len = des_col - pre_des_col; | |
| 148 for (int des_col_index = pre_des_col + 1; des_col_index < des_col; | |
| 149 des_col_index++) { | |
| 150 pWeight = (PixelWeight*)(m_pWeightTables + des_col_index * m_ItemSize); | |
| 151 pWeight->m_SrcStart = src_col - 1; | |
| 152 pWeight->m_SrcEnd = src_col; | |
| 153 pWeight->m_Weights[0] = | |
| 154 bInterpol ? FXSYS_round((FX_FLOAT)( | |
| 155 ((FX_FLOAT)des_col - (FX_FLOAT)des_col_index) / | |
| 156 (FX_FLOAT)des_col_len * 65536)) | |
| 157 : 65536; | |
| 158 pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0]; | |
| 159 } | |
| 160 pre_des_col = des_col; | |
| 161 } | |
| 162 return; | |
| 163 } | |
| 164 for (int des_col = 0; des_col < dest_len; des_col++) { | |
| 165 double src_col_f = des_col / scale; | |
| 166 int src_col = FXSYS_round((FX_FLOAT)src_col_f); | |
| 167 PixelWeight* pWeight = | |
| 168 (PixelWeight*)(m_pWeightTables + des_col * m_ItemSize); | |
| 169 pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col; | |
| 170 pWeight->m_Weights[0] = 65536; | |
| 171 pWeight->m_Weights[1] = 0; | |
| 172 } | |
| 173 } | |
| 174 void CFXCODEC_VertTable::Calc(int dest_len, int src_len) { | |
| 175 if (m_pWeightTables) { | |
| 176 FX_Free(m_pWeightTables); | |
| 177 } | |
| 178 double scale = (double)dest_len / (double)src_len; | |
| 179 m_ItemSize = sizeof(int) * 4; | |
| 180 int size = dest_len * m_ItemSize + 4; | |
| 181 m_pWeightTables = FX_Alloc(uint8_t, size); | |
| 182 if (m_pWeightTables == NULL) { | |
| 183 return; | |
| 184 } | |
| 185 FXSYS_memset(m_pWeightTables, 0, size); | |
| 186 if (scale > 1) { | |
| 187 double step = 0.0; | |
| 188 int src_row = 0; | |
| 189 while (step < (double)dest_len) { | |
| 190 int start_step = (int)step; | |
| 191 step = scale * (++src_row); | |
| 192 int end_step = (int)step; | |
| 193 if (end_step >= dest_len) { | |
| 194 end_step = dest_len; | |
| 195 for (int des_row = start_step; des_row < end_step; des_row++) { | |
| 196 PixelWeight* pWeight = | |
| 197 (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); | |
| 198 pWeight->m_SrcStart = start_step; | |
| 199 pWeight->m_SrcEnd = start_step; | |
| 200 pWeight->m_Weights[0] = 65536; | |
| 201 pWeight->m_Weights[1] = 0; | |
| 202 } | |
| 203 return; | |
| 204 } | |
| 205 int length = end_step - start_step; | |
| 206 { | |
| 207 PixelWeight* pWeight = | |
| 208 (PixelWeight*)(m_pWeightTables + start_step * m_ItemSize); | |
| 209 pWeight->m_SrcStart = start_step; | |
| 210 pWeight->m_SrcEnd = start_step; | |
| 211 pWeight->m_Weights[0] = 65536; | |
| 212 pWeight->m_Weights[1] = 0; | |
| 213 } | |
| 214 for (int des_row = start_step + 1; des_row < end_step; des_row++) { | |
| 215 PixelWeight* pWeight = | |
| 216 (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); | |
| 217 pWeight->m_SrcStart = start_step; | |
| 218 pWeight->m_SrcEnd = end_step; | |
| 219 pWeight->m_Weights[0] = FXSYS_round((FX_FLOAT)(end_step - des_row) / | |
| 220 (FX_FLOAT)length * 65536); | |
| 221 pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0]; | |
| 222 } | |
| 223 } | |
| 224 } else { | |
| 225 for (int des_row = 0; des_row < dest_len; des_row++) { | |
| 226 PixelWeight* pWeight = | |
| 227 (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); | |
| 228 pWeight->m_SrcStart = des_row; | |
| 229 pWeight->m_SrcEnd = des_row; | |
| 230 pWeight->m_Weights[0] = 65536; | |
| 231 pWeight->m_Weights[1] = 0; | |
| 232 } | |
| 233 } | |
| 234 } | |
| 235 CCodec_ProgressiveDecoder::CCodec_ProgressiveDecoder( | |
| 236 CCodec_ModuleMgr* pCodecMgr) { | |
| 237 m_pFile = NULL; | |
| 238 m_pJpegContext = NULL; | |
| 239 m_pPngContext = NULL; | |
| 240 m_pGifContext = NULL; | |
| 241 m_pBmpContext = NULL; | |
| 242 m_pTiffContext = NULL; | |
| 243 m_pCodecMgr = NULL; | |
| 244 m_pSrcBuf = NULL; | |
| 245 m_pDecodeBuf = NULL; | |
| 246 m_pDeviceBitmap = NULL; | |
| 247 m_pSrcPalette = NULL; | |
| 248 m_pCodecMgr = pCodecMgr; | |
| 249 m_offSet = 0; | |
| 250 m_SrcSize = 0; | |
| 251 m_ScanlineSize = 0; | |
| 252 m_SrcWidth = m_SrcHeight = 0; | |
| 253 m_SrcComponents = 0; | |
| 254 m_SrcBPC = 0; | |
| 255 m_SrcPassNumber = 0; | |
| 256 m_clipBox = FX_RECT(0, 0, 0, 0); | |
| 257 m_imagType = FXCODEC_IMAGE_UNKNOWN; | |
| 258 m_status = FXCODEC_STATUS_DECODE_FINISH; | |
| 259 m_TransMethod = -1; | |
| 260 m_SrcRow = 0; | |
| 261 m_SrcFormat = FXCodec_Invalid; | |
| 262 m_bInterpol = TRUE; | |
| 263 m_FrameNumber = 0; | |
| 264 m_FrameCur = 0; | |
| 265 m_SrcPaletteNumber = 0; | |
| 266 m_GifPltNumber = 0; | |
| 267 m_GifBgIndex = 0; | |
| 268 m_pGifPalette = NULL; | |
| 269 m_GifTransIndex = -1; | |
| 270 m_GifFrameRect = FX_RECT(0, 0, 0, 0); | |
| 271 m_BmpIsTopBottom = FALSE; | |
| 272 } | |
| 273 CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder() { | |
| 274 m_pFile = NULL; | |
| 275 if (m_pJpegContext) { | |
| 276 m_pCodecMgr->GetJpegModule()->Finish(m_pJpegContext); | |
| 277 } | |
| 278 if (m_pPngContext) { | |
| 279 m_pCodecMgr->GetPngModule()->Finish(m_pPngContext); | |
| 280 } | |
| 281 if (m_pGifContext) { | |
| 282 m_pCodecMgr->GetGifModule()->Finish(m_pGifContext); | |
| 283 } | |
| 284 if (m_pBmpContext) { | |
| 285 m_pCodecMgr->GetBmpModule()->Finish(m_pBmpContext); | |
| 286 } | |
| 287 if (m_pTiffContext) { | |
| 288 m_pCodecMgr->GetTiffModule()->DestroyDecoder(m_pTiffContext); | |
| 289 } | |
| 290 FX_Free(m_pSrcBuf); | |
| 291 FX_Free(m_pDecodeBuf); | |
| 292 FX_Free(m_pSrcPalette); | |
| 293 } | |
| 294 FX_BOOL CCodec_ProgressiveDecoder::JpegReadMoreData( | |
| 295 ICodec_JpegModule* pJpegModule, | |
| 296 FXCODEC_STATUS& err_status) { | |
| 297 FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); | |
| 298 if (dwSize <= m_offSet) { | |
| 299 return FALSE; | |
| 300 } | |
| 301 dwSize = dwSize - m_offSet; | |
| 302 FX_DWORD dwAvail = pJpegModule->GetAvailInput(m_pJpegContext, NULL); | |
| 303 if (dwAvail == m_SrcSize) { | |
| 304 if (dwSize > FXCODEC_BLOCK_SIZE) { | |
| 305 dwSize = FXCODEC_BLOCK_SIZE; | |
| 306 } | |
| 307 m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / | |
| 308 FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; | |
| 309 m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); | |
| 310 if (!m_pSrcBuf) { | |
| 311 err_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 312 return FALSE; | |
| 313 } | |
| 314 } else { | |
| 315 FX_DWORD dwConsume = m_SrcSize - dwAvail; | |
| 316 if (dwAvail) { | |
| 317 FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); | |
| 318 } | |
| 319 if (dwSize > dwConsume) { | |
| 320 dwSize = dwConsume; | |
| 321 } | |
| 322 } | |
| 323 if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { | |
| 324 err_status = FXCODEC_STATUS_ERR_READ; | |
| 325 return FALSE; | |
| 326 } | |
| 327 m_offSet += dwSize; | |
| 328 pJpegModule->Input(m_pJpegContext, m_pSrcBuf, dwSize + dwAvail); | |
| 329 return TRUE; | |
| 330 } | |
| 331 FX_BOOL CCodec_ProgressiveDecoder::PngReadHeaderFunc(void* pModule, | |
| 332 int width, | |
| 333 int height, | |
| 334 int bpc, | |
| 335 int pass, | |
| 336 int* color_type, | |
| 337 double* gamma) { | |
| 338 CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; | |
| 339 if (pCodec->m_pDeviceBitmap == NULL) { | |
| 340 pCodec->m_SrcWidth = width; | |
| 341 pCodec->m_SrcHeight = height; | |
| 342 pCodec->m_SrcBPC = bpc; | |
| 343 pCodec->m_SrcPassNumber = pass; | |
| 344 pCodec->m_SrcComponents = | |
| 345 *color_type == 0 ? 1 : *color_type == 2 | |
| 346 ? 3 | |
| 347 : *color_type == 3 | |
| 348 ? 4 | |
| 349 : *color_type == 4 | |
| 350 ? 2 | |
| 351 : *color_type == 6 ? 4 : 0; | |
| 352 pCodec->m_clipBox = FX_RECT(0, 0, width, height); | |
| 353 return FALSE; | |
| 354 } | |
| 355 FXDIB_Format format = pCodec->m_pDeviceBitmap->GetFormat(); | |
| 356 switch (format) { | |
| 357 case FXDIB_1bppMask: | |
| 358 case FXDIB_1bppRgb: | |
| 359 ASSERT(FALSE); | |
| 360 return FALSE; | |
| 361 case FXDIB_8bppMask: | |
| 362 case FXDIB_8bppRgb: | |
| 363 *color_type = 0; | |
| 364 break; | |
| 365 case FXDIB_Rgb: | |
| 366 *color_type = 2; | |
| 367 break; | |
| 368 case FXDIB_Rgb32: | |
| 369 case FXDIB_Argb: | |
| 370 *color_type = 6; | |
| 371 break; | |
| 372 default: | |
| 373 ASSERT(FALSE); | |
| 374 return FALSE; | |
| 375 } | |
| 376 *gamma = FXCODEC_PNG_GAMMA; | |
| 377 return TRUE; | |
| 378 } | |
| 379 FX_BOOL CCodec_ProgressiveDecoder::PngAskScanlineBufFunc(void* pModule, | |
| 380 int line, | |
| 381 uint8_t*& src_buf) { | |
| 382 CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; | |
| 383 CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; | |
| 384 if (!pDIBitmap) { | |
| 385 ASSERT(false); | |
| 386 return FALSE; | |
| 387 } | |
| 388 if (line >= pCodec->m_clipBox.top && line < pCodec->m_clipBox.bottom) { | |
| 389 double scale_y = | |
| 390 (double)pCodec->m_sizeY / (double)pCodec->m_clipBox.Height(); | |
| 391 int32_t row = | |
| 392 (int32_t)((line - pCodec->m_clipBox.top) * scale_y) + pCodec->m_startY; | |
| 393 uint8_t* src_scan = (uint8_t*)pDIBitmap->GetScanline(row); | |
| 394 uint8_t* des_scan = pCodec->m_pDecodeBuf; | |
| 395 src_buf = pCodec->m_pDecodeBuf; | |
| 396 int32_t src_Bpp = pDIBitmap->GetBPP() >> 3; | |
| 397 int32_t des_Bpp = (pCodec->m_SrcFormat & 0xff) >> 3; | |
| 398 int32_t src_left = pCodec->m_startX; | |
| 399 int32_t des_left = pCodec->m_clipBox.left; | |
| 400 src_scan += src_left * src_Bpp; | |
| 401 des_scan += des_left * des_Bpp; | |
| 402 for (int32_t src_col = 0; src_col < pCodec->m_sizeX; src_col++) { | |
| 403 PixelWeight* pPixelWeights = | |
| 404 pCodec->m_WeightHorzOO.GetPixelWeight(src_col); | |
| 405 if (pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd) { | |
| 406 continue; | |
| 407 } | |
| 408 switch (pDIBitmap->GetFormat()) { | |
| 409 case FXDIB_1bppMask: | |
| 410 case FXDIB_1bppRgb: | |
| 411 ASSERT(FALSE); | |
| 412 return FALSE; | |
| 413 case FXDIB_8bppMask: | |
| 414 case FXDIB_8bppRgb: { | |
| 415 if (pDIBitmap->GetPalette()) { | |
| 416 return FALSE; | |
| 417 } | |
| 418 FX_DWORD des_g = 0; | |
| 419 des_g += pPixelWeights->m_Weights[0] * src_scan[src_col]; | |
| 420 des_scan[pPixelWeights->m_SrcStart] = (uint8_t)(des_g >> 16); | |
| 421 } break; | |
| 422 case FXDIB_Rgb: | |
| 423 case FXDIB_Rgb32: { | |
| 424 FX_DWORD des_b = 0, des_g = 0, des_r = 0; | |
| 425 const uint8_t* p = src_scan + src_col * src_Bpp; | |
| 426 des_b += pPixelWeights->m_Weights[0] * (*p++); | |
| 427 des_g += pPixelWeights->m_Weights[0] * (*p++); | |
| 428 des_r += pPixelWeights->m_Weights[0] * (*p); | |
| 429 uint8_t* pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp]; | |
| 430 *pDes++ = (uint8_t)((des_b) >> 16); | |
| 431 *pDes++ = (uint8_t)((des_g) >> 16); | |
| 432 *pDes = (uint8_t)((des_r) >> 16); | |
| 433 } break; | |
| 434 case FXDIB_Argb: { | |
| 435 FX_DWORD des_r = 0, des_g = 0, des_b = 0; | |
| 436 const uint8_t* p = src_scan + src_col * src_Bpp; | |
| 437 des_b += pPixelWeights->m_Weights[0] * (*p++); | |
| 438 des_g += pPixelWeights->m_Weights[0] * (*p++); | |
| 439 des_r += pPixelWeights->m_Weights[0] * (*p++); | |
| 440 uint8_t* pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp]; | |
| 441 *pDes++ = (uint8_t)((des_b) >> 16); | |
| 442 *pDes++ = (uint8_t)((des_g) >> 16); | |
| 443 *pDes++ = (uint8_t)((des_r) >> 16); | |
| 444 *pDes = *p; | |
| 445 } break; | |
| 446 default: | |
| 447 return FALSE; | |
| 448 } | |
| 449 } | |
| 450 } | |
| 451 return TRUE; | |
| 452 } | |
| 453 void CCodec_ProgressiveDecoder::PngOneOneMapResampleHorz( | |
| 454 CFX_DIBitmap* pDeviceBitmap, | |
| 455 int32_t des_line, | |
| 456 uint8_t* src_scan, | |
| 457 FXCodec_Format src_format) { | |
| 458 uint8_t* des_scan = (uint8_t*)pDeviceBitmap->GetScanline(des_line); | |
| 459 int32_t src_Bpp = (m_SrcFormat & 0xff) >> 3; | |
| 460 int32_t des_Bpp = pDeviceBitmap->GetBPP() >> 3; | |
| 461 int32_t src_left = m_clipBox.left; | |
| 462 int32_t des_left = m_startX; | |
| 463 src_scan += src_left * src_Bpp; | |
| 464 des_scan += des_left * des_Bpp; | |
| 465 for (int32_t des_col = 0; des_col < m_sizeX; des_col++) { | |
| 466 PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(des_col); | |
| 467 switch (pDeviceBitmap->GetFormat()) { | |
| 468 case FXDIB_1bppMask: | |
| 469 case FXDIB_1bppRgb: | |
| 470 ASSERT(FALSE); | |
| 471 return; | |
| 472 case FXDIB_8bppMask: | |
| 473 case FXDIB_8bppRgb: { | |
| 474 if (pDeviceBitmap->GetPalette()) { | |
| 475 return; | |
| 476 } | |
| 477 FX_DWORD des_g = 0; | |
| 478 des_g += | |
| 479 pPixelWeights->m_Weights[0] * src_scan[pPixelWeights->m_SrcStart]; | |
| 480 des_g += | |
| 481 pPixelWeights->m_Weights[1] * src_scan[pPixelWeights->m_SrcEnd]; | |
| 482 *des_scan++ = (uint8_t)(des_g >> 16); | |
| 483 } break; | |
| 484 case FXDIB_Rgb: | |
| 485 case FXDIB_Rgb32: { | |
| 486 FX_DWORD des_b = 0, des_g = 0, des_r = 0; | |
| 487 const uint8_t* p = src_scan; | |
| 488 p = src_scan + pPixelWeights->m_SrcStart * src_Bpp; | |
| 489 des_b += pPixelWeights->m_Weights[0] * (*p++); | |
| 490 des_g += pPixelWeights->m_Weights[0] * (*p++); | |
| 491 des_r += pPixelWeights->m_Weights[0] * (*p); | |
| 492 p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp; | |
| 493 des_b += pPixelWeights->m_Weights[1] * (*p++); | |
| 494 des_g += pPixelWeights->m_Weights[1] * (*p++); | |
| 495 des_r += pPixelWeights->m_Weights[1] * (*p); | |
| 496 *des_scan++ = (uint8_t)((des_b) >> 16); | |
| 497 *des_scan++ = (uint8_t)((des_g) >> 16); | |
| 498 *des_scan++ = (uint8_t)((des_r) >> 16); | |
| 499 des_scan += des_Bpp - 3; | |
| 500 } break; | |
| 501 case FXDIB_Argb: { | |
| 502 FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; | |
| 503 const uint8_t* p = src_scan; | |
| 504 p = src_scan + pPixelWeights->m_SrcStart * src_Bpp; | |
| 505 des_b += pPixelWeights->m_Weights[0] * (*p++); | |
| 506 des_g += pPixelWeights->m_Weights[0] * (*p++); | |
| 507 des_r += pPixelWeights->m_Weights[0] * (*p++); | |
| 508 des_a += pPixelWeights->m_Weights[0] * (*p); | |
| 509 p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp; | |
| 510 des_b += pPixelWeights->m_Weights[1] * (*p++); | |
| 511 des_g += pPixelWeights->m_Weights[1] * (*p++); | |
| 512 des_r += pPixelWeights->m_Weights[1] * (*p++); | |
| 513 des_a += pPixelWeights->m_Weights[1] * (*p); | |
| 514 *des_scan++ = (uint8_t)((des_b) >> 16); | |
| 515 *des_scan++ = (uint8_t)((des_g) >> 16); | |
| 516 *des_scan++ = (uint8_t)((des_r) >> 16); | |
| 517 *des_scan++ = (uint8_t)((des_a) >> 16); | |
| 518 } break; | |
| 519 default: | |
| 520 return; | |
| 521 } | |
| 522 } | |
| 523 } | |
| 524 void CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc(void* pModule, | |
| 525 int pass, | |
| 526 int line) { | |
| 527 CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; | |
| 528 CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; | |
| 529 ASSERT(pDIBitmap); | |
| 530 int src_top = pCodec->m_clipBox.top; | |
| 531 int src_bottom = pCodec->m_clipBox.bottom; | |
| 532 int des_top = pCodec->m_startY; | |
| 533 int src_hei = pCodec->m_clipBox.Height(); | |
| 534 int des_hei = pCodec->m_sizeY; | |
| 535 if (line >= src_top && line < src_bottom) { | |
| 536 double scale_y = (double)des_hei / (double)src_hei; | |
| 537 int src_row = line - src_top; | |
| 538 int des_row = (int)(src_row * scale_y) + des_top; | |
| 539 if (des_row >= des_top + des_hei) { | |
| 540 return; | |
| 541 } | |
| 542 pCodec->PngOneOneMapResampleHorz(pDIBitmap, des_row, pCodec->m_pDecodeBuf, | |
| 543 pCodec->m_SrcFormat); | |
| 544 if (pCodec->m_SrcPassNumber == 1 && scale_y > 1.0) { | |
| 545 pCodec->ResampleVert(pDIBitmap, scale_y, des_row); | |
| 546 return; | |
| 547 } | |
| 548 if (pass == 6 && scale_y > 1.0) { | |
| 549 pCodec->ResampleVert(pDIBitmap, scale_y, des_row); | |
| 550 } | |
| 551 } | |
| 552 } | |
| 553 FX_BOOL CCodec_ProgressiveDecoder::GifReadMoreData(ICodec_GifModule* pGifModule, | |
| 554 FXCODEC_STATUS& err_status) { | |
| 555 FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); | |
| 556 if (dwSize <= m_offSet) { | |
| 557 return FALSE; | |
| 558 } | |
| 559 dwSize = dwSize - m_offSet; | |
| 560 FX_DWORD dwAvail = pGifModule->GetAvailInput(m_pGifContext, NULL); | |
| 561 if (dwAvail == m_SrcSize) { | |
| 562 if (dwSize > FXCODEC_BLOCK_SIZE) { | |
| 563 dwSize = FXCODEC_BLOCK_SIZE; | |
| 564 } | |
| 565 m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / | |
| 566 FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; | |
| 567 m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); | |
| 568 if (!m_pSrcBuf) { | |
| 569 err_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 570 return FALSE; | |
| 571 } | |
| 572 } else { | |
| 573 FX_DWORD dwConsume = m_SrcSize - dwAvail; | |
| 574 if (dwAvail) { | |
| 575 FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); | |
| 576 } | |
| 577 if (dwSize > dwConsume) { | |
| 578 dwSize = dwConsume; | |
| 579 } | |
| 580 } | |
| 581 if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { | |
| 582 err_status = FXCODEC_STATUS_ERR_READ; | |
| 583 return FALSE; | |
| 584 } | |
| 585 m_offSet += dwSize; | |
| 586 pGifModule->Input(m_pGifContext, m_pSrcBuf, dwSize + dwAvail); | |
| 587 return TRUE; | |
| 588 } | |
| 589 void CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback( | |
| 590 void* pModule, | |
| 591 FX_DWORD& cur_pos) { | |
| 592 CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; | |
| 593 FX_DWORD remain_size = | |
| 594 pCodec->m_pCodecMgr->GetGifModule()->GetAvailInput(pCodec->m_pGifContext); | |
| 595 cur_pos = pCodec->m_offSet - remain_size; | |
| 596 } | |
| 597 uint8_t* CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback( | |
| 598 void* pModule, | |
| 599 int32_t frame_num, | |
| 600 int32_t pal_size) { | |
| 601 return FX_Alloc(uint8_t, pal_size); | |
| 602 } | |
| 603 FX_BOOL CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback( | |
| 604 void* pModule, | |
| 605 FX_DWORD rcd_pos, | |
| 606 const FX_RECT& img_rc, | |
| 607 int32_t pal_num, | |
| 608 void* pal_ptr, | |
| 609 int32_t delay_time, | |
| 610 FX_BOOL user_input, | |
| 611 int32_t trans_index, | |
| 612 int32_t disposal_method, | |
| 613 FX_BOOL interlace) { | |
| 614 CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; | |
| 615 pCodec->m_offSet = rcd_pos; | |
| 616 FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; | |
| 617 if (!pCodec->GifReadMoreData(pCodec->m_pCodecMgr->GetGifModule(), | |
| 618 error_status)) { | |
| 619 return FALSE; | |
| 620 } | |
| 621 uint8_t* pPalette = NULL; | |
| 622 if (pal_num != 0 && pal_ptr) { | |
| 623 pPalette = (uint8_t*)pal_ptr; | |
| 624 } else { | |
| 625 pal_num = pCodec->m_GifPltNumber; | |
| 626 pPalette = pCodec->m_pGifPalette; | |
| 627 } | |
| 628 if (pCodec->m_pSrcPalette == NULL) { | |
| 629 pCodec->m_pSrcPalette = FX_Alloc(FX_ARGB, pal_num); | |
| 630 } else if (pal_num > pCodec->m_SrcPaletteNumber) { | |
| 631 pCodec->m_pSrcPalette = FX_Realloc(FX_ARGB, pCodec->m_pSrcPalette, pal_num); | |
| 632 } | |
| 633 if (pCodec->m_pSrcPalette == NULL) { | |
| 634 return FALSE; | |
| 635 } | |
| 636 pCodec->m_SrcPaletteNumber = pal_num; | |
| 637 for (int i = 0; i < pal_num; i++) { | |
| 638 FX_DWORD j = i * 3; | |
| 639 pCodec->m_pSrcPalette[i] = | |
| 640 ArgbEncode(0xff, pPalette[j], pPalette[j + 1], pPalette[j + 2]); | |
| 641 } | |
| 642 pCodec->m_GifTransIndex = trans_index; | |
| 643 pCodec->m_GifFrameRect = img_rc; | |
| 644 pCodec->m_SrcPassNumber = interlace ? 4 : 1; | |
| 645 int32_t pal_index = pCodec->m_GifBgIndex; | |
| 646 CFX_DIBitmap* pDevice = pCodec->m_pDeviceBitmap; | |
| 647 if (trans_index >= pal_num) { | |
| 648 trans_index = -1; | |
| 649 } | |
| 650 if (trans_index != -1) { | |
| 651 pCodec->m_pSrcPalette[trans_index] &= 0x00ffffff; | |
| 652 if (pDevice->HasAlpha()) { | |
| 653 pal_index = trans_index; | |
| 654 } | |
| 655 } | |
| 656 int startX = pCodec->m_startX; | |
| 657 int startY = pCodec->m_startY; | |
| 658 int sizeX = pCodec->m_sizeX; | |
| 659 int sizeY = pCodec->m_sizeY; | |
| 660 int Bpp = pDevice->GetBPP() / 8; | |
| 661 FX_ARGB argb = pCodec->m_pSrcPalette[pal_index]; | |
| 662 for (int row = 0; row < sizeY; row++) { | |
| 663 uint8_t* pScanline = | |
| 664 (uint8_t*)pDevice->GetScanline(row + startY) + startX * Bpp; | |
| 665 switch (pCodec->m_TransMethod) { | |
| 666 case 3: { | |
| 667 uint8_t gray = | |
| 668 FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); | |
| 669 FXSYS_memset(pScanline, gray, sizeX); | |
| 670 break; | |
| 671 } | |
| 672 case 8: { | |
| 673 for (int col = 0; col < sizeX; col++) { | |
| 674 *pScanline++ = FXARGB_B(argb); | |
| 675 *pScanline++ = FXARGB_G(argb); | |
| 676 *pScanline++ = FXARGB_R(argb); | |
| 677 pScanline += Bpp - 3; | |
| 678 } | |
| 679 break; | |
| 680 } | |
| 681 case 12: { | |
| 682 for (int col = 0; col < sizeX; col++) { | |
| 683 FXARGB_SETDIB(pScanline, argb); | |
| 684 pScanline += 4; | |
| 685 } | |
| 686 break; | |
| 687 } | |
| 688 } | |
| 689 } | |
| 690 return TRUE; | |
| 691 } | |
| 692 void CCodec_ProgressiveDecoder::GifReadScanlineCallback(void* pModule, | |
| 693 int32_t row_num, | |
| 694 uint8_t* row_buf) { | |
| 695 CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; | |
| 696 CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; | |
| 697 ASSERT(pDIBitmap); | |
| 698 int32_t img_width = pCodec->m_GifFrameRect.Width(); | |
| 699 if (!pDIBitmap->HasAlpha()) { | |
| 700 uint8_t* byte_ptr = row_buf; | |
| 701 for (int i = 0; i < img_width; i++) { | |
| 702 if (*byte_ptr == pCodec->m_GifTransIndex) { | |
| 703 *byte_ptr = pCodec->m_GifBgIndex; | |
| 704 } | |
| 705 byte_ptr++; | |
| 706 } | |
| 707 } | |
| 708 int32_t pal_index = pCodec->m_GifBgIndex; | |
| 709 if (pCodec->m_GifTransIndex != -1 && pCodec->m_pDeviceBitmap->HasAlpha()) { | |
| 710 pal_index = pCodec->m_GifTransIndex; | |
| 711 } | |
| 712 FXSYS_memset(pCodec->m_pDecodeBuf, pal_index, pCodec->m_SrcWidth); | |
| 713 bool bLastPass = (row_num % 2) == 1; | |
| 714 int32_t line = row_num + pCodec->m_GifFrameRect.top; | |
| 715 int32_t left = pCodec->m_GifFrameRect.left; | |
| 716 FXSYS_memcpy(pCodec->m_pDecodeBuf + left, row_buf, img_width); | |
| 717 int src_top = pCodec->m_clipBox.top; | |
| 718 int src_bottom = pCodec->m_clipBox.bottom; | |
| 719 int des_top = pCodec->m_startY; | |
| 720 int src_hei = pCodec->m_clipBox.Height(); | |
| 721 int des_hei = pCodec->m_sizeY; | |
| 722 if (line >= src_top && line < src_bottom) { | |
| 723 double scale_y = (double)des_hei / (double)src_hei; | |
| 724 int src_row = line - src_top; | |
| 725 int des_row = (int)(src_row * scale_y) + des_top; | |
| 726 if (des_row >= des_top + des_hei) { | |
| 727 return; | |
| 728 } | |
| 729 pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf, | |
| 730 pCodec->m_SrcFormat); | |
| 731 if (scale_y > 1.0 && | |
| 732 (!pCodec->m_bInterpol || pCodec->m_SrcPassNumber == 1)) { | |
| 733 pCodec->ResampleVert(pDIBitmap, scale_y, des_row); | |
| 734 return; | |
| 735 } | |
| 736 if (scale_y > 1.0) { | |
| 737 int des_bottom = des_top + pCodec->m_sizeY; | |
| 738 int des_Bpp = pDIBitmap->GetBPP() >> 3; | |
| 739 FX_DWORD des_ScanOffet = pCodec->m_startX * des_Bpp; | |
| 740 if (des_row + (int)scale_y >= des_bottom - 1) { | |
| 741 uint8_t* scan_src = | |
| 742 (uint8_t*)pDIBitmap->GetScanline(des_row) + des_ScanOffet; | |
| 743 int cur_row = des_row; | |
| 744 while (++cur_row < des_bottom) { | |
| 745 uint8_t* scan_des = | |
| 746 (uint8_t*)pDIBitmap->GetScanline(cur_row) + des_ScanOffet; | |
| 747 FX_DWORD size = pCodec->m_sizeX * des_Bpp; | |
| 748 FXSYS_memcpy(scan_des, scan_src, size); | |
| 749 } | |
| 750 } | |
| 751 if (bLastPass) { | |
| 752 pCodec->GifDoubleLineResampleVert(pDIBitmap, scale_y, des_row); | |
| 753 } | |
| 754 } | |
| 755 } | |
| 756 } | |
| 757 void CCodec_ProgressiveDecoder::GifDoubleLineResampleVert( | |
| 758 CFX_DIBitmap* pDeviceBitmap, | |
| 759 double scale_y, | |
| 760 int des_row) { | |
| 761 int des_Bpp = pDeviceBitmap->GetBPP() >> 3; | |
| 762 FX_DWORD des_ScanOffet = m_startX * des_Bpp; | |
| 763 int des_top = m_startY; | |
| 764 int des_row_1 = des_row - int(2 * scale_y); | |
| 765 if (des_row_1 < des_top) { | |
| 766 des_row_1 = des_top; | |
| 767 } | |
| 768 for (; des_row_1 < des_row; des_row_1++) { | |
| 769 uint8_t* scan_des = | |
| 770 (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; | |
| 771 PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); | |
| 772 const uint8_t* scan_src1 = | |
| 773 pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + | |
| 774 des_ScanOffet; | |
| 775 const uint8_t* scan_src2 = | |
| 776 pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet; | |
| 777 for (int des_col = 0; des_col < m_sizeX; des_col++) { | |
| 778 switch (pDeviceBitmap->GetFormat()) { | |
| 779 case FXDIB_Invalid: | |
| 780 case FXDIB_1bppMask: | |
| 781 case FXDIB_1bppRgb: | |
| 782 return; | |
| 783 case FXDIB_8bppMask: | |
| 784 case FXDIB_8bppRgb: { | |
| 785 if (pDeviceBitmap->GetPalette()) { | |
| 786 return; | |
| 787 } | |
| 788 int des_g = 0; | |
| 789 des_g += pWeight->m_Weights[0] * (*scan_src1++); | |
| 790 des_g += pWeight->m_Weights[1] * (*scan_src2++); | |
| 791 *scan_des++ = (uint8_t)(des_g >> 16); | |
| 792 } break; | |
| 793 case FXDIB_Rgb: | |
| 794 case FXDIB_Rgb32: { | |
| 795 FX_DWORD des_b = 0, des_g = 0, des_r = 0; | |
| 796 des_b += pWeight->m_Weights[0] * (*scan_src1++); | |
| 797 des_g += pWeight->m_Weights[0] * (*scan_src1++); | |
| 798 des_r += pWeight->m_Weights[0] * (*scan_src1++); | |
| 799 scan_src1 += des_Bpp - 3; | |
| 800 des_b += pWeight->m_Weights[1] * (*scan_src2++); | |
| 801 des_g += pWeight->m_Weights[1] * (*scan_src2++); | |
| 802 des_r += pWeight->m_Weights[1] * (*scan_src2++); | |
| 803 scan_src2 += des_Bpp - 3; | |
| 804 *scan_des++ = (uint8_t)((des_b) >> 16); | |
| 805 *scan_des++ = (uint8_t)((des_g) >> 16); | |
| 806 *scan_des++ = (uint8_t)((des_r) >> 16); | |
| 807 scan_des += des_Bpp - 3; | |
| 808 } break; | |
| 809 case FXDIB_Argb: { | |
| 810 FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; | |
| 811 des_b += pWeight->m_Weights[0] * (*scan_src1++); | |
| 812 des_g += pWeight->m_Weights[0] * (*scan_src1++); | |
| 813 des_r += pWeight->m_Weights[0] * (*scan_src1++); | |
| 814 des_a += pWeight->m_Weights[0] * (*scan_src1++); | |
| 815 des_b += pWeight->m_Weights[1] * (*scan_src2++); | |
| 816 des_g += pWeight->m_Weights[1] * (*scan_src2++); | |
| 817 des_r += pWeight->m_Weights[1] * (*scan_src2++); | |
| 818 des_a += pWeight->m_Weights[1] * (*scan_src2++); | |
| 819 *scan_des++ = (uint8_t)((des_b) >> 16); | |
| 820 *scan_des++ = (uint8_t)((des_g) >> 16); | |
| 821 *scan_des++ = (uint8_t)((des_r) >> 16); | |
| 822 *scan_des++ = (uint8_t)((des_a) >> 16); | |
| 823 } break; | |
| 824 default: | |
| 825 return; | |
| 826 } | |
| 827 } | |
| 828 } | |
| 829 int des_bottom = des_top + m_sizeY - 1; | |
| 830 if (des_row + (int)(2 * scale_y) >= des_bottom && | |
| 831 des_row + (int)scale_y < des_bottom) { | |
| 832 GifDoubleLineResampleVert(pDeviceBitmap, scale_y, des_row + (int)scale_y); | |
| 833 } | |
| 834 } | |
| 835 FX_BOOL CCodec_ProgressiveDecoder::BmpReadMoreData(ICodec_BmpModule* pBmpModule, | |
| 836 FXCODEC_STATUS& err_status) { | |
| 837 FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); | |
| 838 if (dwSize <= m_offSet) { | |
| 839 return FALSE; | |
| 840 } | |
| 841 dwSize = dwSize - m_offSet; | |
| 842 FX_DWORD dwAvail = pBmpModule->GetAvailInput(m_pBmpContext, NULL); | |
| 843 if (dwAvail == m_SrcSize) { | |
| 844 if (dwSize > FXCODEC_BLOCK_SIZE) { | |
| 845 dwSize = FXCODEC_BLOCK_SIZE; | |
| 846 } | |
| 847 m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / | |
| 848 FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; | |
| 849 m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); | |
| 850 if (!m_pSrcBuf) { | |
| 851 err_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 852 return FALSE; | |
| 853 } | |
| 854 } else { | |
| 855 FX_DWORD dwConsume = m_SrcSize - dwAvail; | |
| 856 if (dwAvail) { | |
| 857 FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); | |
| 858 } | |
| 859 if (dwSize > dwConsume) { | |
| 860 dwSize = dwConsume; | |
| 861 } | |
| 862 } | |
| 863 if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { | |
| 864 err_status = FXCODEC_STATUS_ERR_READ; | |
| 865 return FALSE; | |
| 866 } | |
| 867 m_offSet += dwSize; | |
| 868 pBmpModule->Input(m_pBmpContext, m_pSrcBuf, dwSize + dwAvail); | |
| 869 return TRUE; | |
| 870 } | |
| 871 FX_BOOL CCodec_ProgressiveDecoder::BmpInputImagePositionBufCallback( | |
| 872 void* pModule, | |
| 873 FX_DWORD rcd_pos) { | |
| 874 CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; | |
| 875 pCodec->m_offSet = rcd_pos; | |
| 876 FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; | |
| 877 if (!pCodec->BmpReadMoreData(pCodec->m_pCodecMgr->GetBmpModule(), | |
| 878 error_status)) { | |
| 879 return FALSE; | |
| 880 } | |
| 881 return TRUE; | |
| 882 } | |
| 883 void CCodec_ProgressiveDecoder::BmpReadScanlineCallback(void* pModule, | |
| 884 int32_t row_num, | |
| 885 uint8_t* row_buf) { | |
| 886 CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; | |
| 887 CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; | |
| 888 ASSERT(pDIBitmap); | |
| 889 FXSYS_memcpy(pCodec->m_pDecodeBuf, row_buf, pCodec->m_ScanlineSize); | |
| 890 int src_top = pCodec->m_clipBox.top; | |
| 891 int src_bottom = pCodec->m_clipBox.bottom; | |
| 892 int des_top = pCodec->m_startY; | |
| 893 int src_hei = pCodec->m_clipBox.Height(); | |
| 894 int des_hei = pCodec->m_sizeY; | |
| 895 if (row_num >= src_top && row_num < src_bottom) { | |
| 896 double scale_y = (double)des_hei / (double)src_hei; | |
| 897 int src_row = row_num - src_top; | |
| 898 int des_row = (int)(src_row * scale_y) + des_top; | |
| 899 if (des_row >= des_top + des_hei) { | |
| 900 return; | |
| 901 } | |
| 902 pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf, | |
| 903 pCodec->m_SrcFormat); | |
| 904 if (scale_y > 1.0) { | |
| 905 if (pCodec->m_BmpIsTopBottom || !pCodec->m_bInterpol) { | |
| 906 pCodec->ResampleVert(pDIBitmap, scale_y, des_row); | |
| 907 return; | |
| 908 } else { | |
| 909 pCodec->ResampleVertBT(pDIBitmap, scale_y, des_row); | |
| 910 } | |
| 911 } | |
| 912 } | |
| 913 } | |
| 914 void CCodec_ProgressiveDecoder::ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, | |
| 915 double scale_y, | |
| 916 int des_row) { | |
| 917 int des_Bpp = pDeviceBitmap->GetBPP() >> 3; | |
| 918 FX_DWORD des_ScanOffet = m_startX * des_Bpp; | |
| 919 int des_top = m_startY; | |
| 920 int des_bottom = m_startY + m_sizeY; | |
| 921 int des_row_1 = des_row + int(scale_y); | |
| 922 if (des_row_1 >= des_bottom - 1) { | |
| 923 uint8_t* scan_src = | |
| 924 (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; | |
| 925 while (++des_row < des_bottom) { | |
| 926 uint8_t* scan_des = | |
| 927 (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; | |
| 928 FX_DWORD size = m_sizeX * des_Bpp; | |
| 929 FXSYS_memcpy(scan_des, scan_src, size); | |
| 930 } | |
| 931 return; | |
| 932 } | |
| 933 for (; des_row_1 > des_row; des_row_1--) { | |
| 934 uint8_t* scan_des = | |
| 935 (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; | |
| 936 PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); | |
| 937 const uint8_t* scan_src1 = | |
| 938 pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + | |
| 939 des_ScanOffet; | |
| 940 const uint8_t* scan_src2 = | |
| 941 pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet; | |
| 942 for (int des_col = 0; des_col < m_sizeX; des_col++) { | |
| 943 switch (pDeviceBitmap->GetFormat()) { | |
| 944 case FXDIB_Invalid: | |
| 945 case FXDIB_1bppMask: | |
| 946 case FXDIB_1bppRgb: | |
| 947 return; | |
| 948 case FXDIB_8bppMask: | |
| 949 case FXDIB_8bppRgb: { | |
| 950 if (pDeviceBitmap->GetPalette()) { | |
| 951 return; | |
| 952 } | |
| 953 int des_g = 0; | |
| 954 des_g += pWeight->m_Weights[0] * (*scan_src1++); | |
| 955 des_g += pWeight->m_Weights[1] * (*scan_src2++); | |
| 956 *scan_des++ = (uint8_t)(des_g >> 16); | |
| 957 } break; | |
| 958 case FXDIB_Rgb: | |
| 959 case FXDIB_Rgb32: { | |
| 960 FX_DWORD des_b = 0, des_g = 0, des_r = 0; | |
| 961 des_b += pWeight->m_Weights[0] * (*scan_src1++); | |
| 962 des_g += pWeight->m_Weights[0] * (*scan_src1++); | |
| 963 des_r += pWeight->m_Weights[0] * (*scan_src1++); | |
| 964 scan_src1 += des_Bpp - 3; | |
| 965 des_b += pWeight->m_Weights[1] * (*scan_src2++); | |
| 966 des_g += pWeight->m_Weights[1] * (*scan_src2++); | |
| 967 des_r += pWeight->m_Weights[1] * (*scan_src2++); | |
| 968 scan_src2 += des_Bpp - 3; | |
| 969 *scan_des++ = (uint8_t)((des_b) >> 16); | |
| 970 *scan_des++ = (uint8_t)((des_g) >> 16); | |
| 971 *scan_des++ = (uint8_t)((des_r) >> 16); | |
| 972 scan_des += des_Bpp - 3; | |
| 973 } break; | |
| 974 case FXDIB_Argb: { | |
| 975 FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; | |
| 976 des_b += pWeight->m_Weights[0] * (*scan_src1++); | |
| 977 des_g += pWeight->m_Weights[0] * (*scan_src1++); | |
| 978 des_r += pWeight->m_Weights[0] * (*scan_src1++); | |
| 979 des_a += pWeight->m_Weights[0] * (*scan_src1++); | |
| 980 des_b += pWeight->m_Weights[1] * (*scan_src2++); | |
| 981 des_g += pWeight->m_Weights[1] * (*scan_src2++); | |
| 982 des_r += pWeight->m_Weights[1] * (*scan_src2++); | |
| 983 des_a += pWeight->m_Weights[1] * (*scan_src2++); | |
| 984 *scan_des++ = (uint8_t)((des_b) >> 16); | |
| 985 *scan_des++ = (uint8_t)((des_g) >> 16); | |
| 986 *scan_des++ = (uint8_t)((des_r) >> 16); | |
| 987 *scan_des++ = (uint8_t)((des_a) >> 16); | |
| 988 } break; | |
| 989 default: | |
| 990 return; | |
| 991 } | |
| 992 } | |
| 993 } | |
| 994 } | |
| 995 FX_BOOL CCodec_ProgressiveDecoder::DetectImageType( | |
| 996 FXCODEC_IMAGE_TYPE imageType, | |
| 997 CFX_DIBAttribute* pAttribute) { | |
| 998 m_offSet = 0; | |
| 999 FX_DWORD size = (FX_DWORD)m_pFile->GetSize(); | |
| 1000 if (size > FXCODEC_BLOCK_SIZE) { | |
| 1001 size = FXCODEC_BLOCK_SIZE; | |
| 1002 } | |
| 1003 FX_Free(m_pSrcBuf); | |
| 1004 m_pSrcBuf = FX_Alloc(uint8_t, size); | |
| 1005 FXSYS_memset(m_pSrcBuf, 0, size); | |
| 1006 m_SrcSize = size; | |
| 1007 switch (imageType) { | |
| 1008 case FXCODEC_IMAGE_BMP: { | |
| 1009 ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); | |
| 1010 if (pBmpModule == NULL) { | |
| 1011 m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 1012 return FALSE; | |
| 1013 } | |
| 1014 pBmpModule->InputImagePositionBufCallback = | |
| 1015 BmpInputImagePositionBufCallback; | |
| 1016 pBmpModule->ReadScanlineCallback = BmpReadScanlineCallback; | |
| 1017 m_pBmpContext = pBmpModule->Start((void*)this); | |
| 1018 if (m_pBmpContext == NULL) { | |
| 1019 m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 1020 return FALSE; | |
| 1021 } | |
| 1022 FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); | |
| 1023 if (!bResult) { | |
| 1024 m_status = FXCODEC_STATUS_ERR_READ; | |
| 1025 return FALSE; | |
| 1026 } | |
| 1027 m_offSet += size; | |
| 1028 pBmpModule->Input(m_pBmpContext, m_pSrcBuf, size); | |
| 1029 FX_DWORD* pPalette = NULL; | |
| 1030 int32_t readResult = pBmpModule->ReadHeader( | |
| 1031 m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom, | |
| 1032 &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute); | |
| 1033 while (readResult == 2) { | |
| 1034 FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; | |
| 1035 if (!BmpReadMoreData(pBmpModule, error_status)) { | |
| 1036 m_status = error_status; | |
| 1037 return FALSE; | |
| 1038 } | |
| 1039 readResult = pBmpModule->ReadHeader( | |
| 1040 m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom, | |
| 1041 &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute); | |
| 1042 } | |
| 1043 if (readResult == 1) { | |
| 1044 m_SrcBPC = 8; | |
| 1045 m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); | |
| 1046 FX_Free(m_pSrcPalette); | |
| 1047 if (m_SrcPaletteNumber) { | |
| 1048 m_pSrcPalette = FX_Alloc(FX_ARGB, m_SrcPaletteNumber); | |
| 1049 FXSYS_memcpy(m_pSrcPalette, pPalette, | |
| 1050 m_SrcPaletteNumber * sizeof(FX_DWORD)); | |
| 1051 } else { | |
| 1052 m_pSrcPalette = nullptr; | |
| 1053 } | |
| 1054 return TRUE; | |
| 1055 } | |
| 1056 if (m_pBmpContext) { | |
| 1057 pBmpModule->Finish(m_pBmpContext); | |
| 1058 m_pBmpContext = NULL; | |
| 1059 } | |
| 1060 m_status = FXCODEC_STATUS_ERR_FORMAT; | |
| 1061 return FALSE; | |
| 1062 } break; | |
| 1063 case FXCODEC_IMAGE_JPG: { | |
| 1064 ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); | |
| 1065 if (pJpegModule == NULL) { | |
| 1066 m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 1067 return FALSE; | |
| 1068 } | |
| 1069 m_pJpegContext = pJpegModule->Start(); | |
| 1070 if (m_pJpegContext == NULL) { | |
| 1071 m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 1072 return FALSE; | |
| 1073 } | |
| 1074 FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); | |
| 1075 if (!bResult) { | |
| 1076 m_status = FXCODEC_STATUS_ERR_READ; | |
| 1077 return FALSE; | |
| 1078 } | |
| 1079 m_offSet += size; | |
| 1080 pJpegModule->Input(m_pJpegContext, m_pSrcBuf, size); | |
| 1081 int32_t readResult = | |
| 1082 pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, | |
| 1083 &m_SrcComponents, pAttribute); | |
| 1084 while (readResult == 2) { | |
| 1085 FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; | |
| 1086 if (!JpegReadMoreData(pJpegModule, error_status)) { | |
| 1087 m_status = error_status; | |
| 1088 return FALSE; | |
| 1089 } | |
| 1090 readResult = | |
| 1091 pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, | |
| 1092 &m_SrcComponents, pAttribute); | |
| 1093 } | |
| 1094 if (!readResult) { | |
| 1095 m_SrcBPC = 8; | |
| 1096 m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); | |
| 1097 return TRUE; | |
| 1098 } | |
| 1099 if (m_pJpegContext) { | |
| 1100 pJpegModule->Finish(m_pJpegContext); | |
| 1101 m_pJpegContext = NULL; | |
| 1102 } | |
| 1103 m_status = FXCODEC_STATUS_ERR_FORMAT; | |
| 1104 return FALSE; | |
| 1105 } break; | |
| 1106 case FXCODEC_IMAGE_PNG: { | |
| 1107 ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); | |
| 1108 if (pPngModule == NULL) { | |
| 1109 m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 1110 return FALSE; | |
| 1111 } | |
| 1112 pPngModule->ReadHeaderCallback = | |
| 1113 CCodec_ProgressiveDecoder::PngReadHeaderFunc; | |
| 1114 pPngModule->AskScanlineBufCallback = | |
| 1115 CCodec_ProgressiveDecoder::PngAskScanlineBufFunc; | |
| 1116 pPngModule->FillScanlineBufCompletedCallback = | |
| 1117 CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc; | |
| 1118 m_pPngContext = pPngModule->Start((void*)this); | |
| 1119 if (m_pPngContext == NULL) { | |
| 1120 m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 1121 return FALSE; | |
| 1122 } | |
| 1123 FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); | |
| 1124 if (!bResult) { | |
| 1125 m_status = FXCODEC_STATUS_ERR_READ; | |
| 1126 return FALSE; | |
| 1127 } | |
| 1128 m_offSet += size; | |
| 1129 bResult = pPngModule->Input(m_pPngContext, m_pSrcBuf, size, pAttribute); | |
| 1130 while (bResult) { | |
| 1131 FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet; | |
| 1132 FX_DWORD input_size = | |
| 1133 remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size; | |
| 1134 if (input_size == 0) { | |
| 1135 if (m_pPngContext) { | |
| 1136 pPngModule->Finish(m_pPngContext); | |
| 1137 } | |
| 1138 m_pPngContext = NULL; | |
| 1139 m_status = FXCODEC_STATUS_ERR_FORMAT; | |
| 1140 return FALSE; | |
| 1141 } | |
| 1142 if (m_pSrcBuf && input_size > m_SrcSize) { | |
| 1143 FX_Free(m_pSrcBuf); | |
| 1144 m_pSrcBuf = FX_Alloc(uint8_t, input_size); | |
| 1145 FXSYS_memset(m_pSrcBuf, 0, input_size); | |
| 1146 m_SrcSize = input_size; | |
| 1147 } | |
| 1148 bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size); | |
| 1149 if (!bResult) { | |
| 1150 m_status = FXCODEC_STATUS_ERR_READ; | |
| 1151 return FALSE; | |
| 1152 } | |
| 1153 m_offSet += input_size; | |
| 1154 bResult = | |
| 1155 pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, pAttribute); | |
| 1156 } | |
| 1157 ASSERT(!bResult); | |
| 1158 if (m_pPngContext) { | |
| 1159 pPngModule->Finish(m_pPngContext); | |
| 1160 m_pPngContext = NULL; | |
| 1161 } | |
| 1162 if (m_SrcPassNumber == 0) { | |
| 1163 m_status = FXCODEC_STATUS_ERR_FORMAT; | |
| 1164 return FALSE; | |
| 1165 } | |
| 1166 } break; | |
| 1167 case FXCODEC_IMAGE_GIF: { | |
| 1168 ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); | |
| 1169 if (pGifModule == NULL) { | |
| 1170 m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 1171 return FALSE; | |
| 1172 } | |
| 1173 pGifModule->RecordCurrentPositionCallback = | |
| 1174 CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback; | |
| 1175 pGifModule->AskLocalPaletteBufCallback = | |
| 1176 CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback; | |
| 1177 pGifModule->InputRecordPositionBufCallback = | |
| 1178 CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback; | |
| 1179 pGifModule->ReadScanlineCallback = | |
| 1180 CCodec_ProgressiveDecoder::GifReadScanlineCallback; | |
| 1181 m_pGifContext = pGifModule->Start((void*)this); | |
| 1182 if (m_pGifContext == NULL) { | |
| 1183 m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 1184 return FALSE; | |
| 1185 } | |
| 1186 FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); | |
| 1187 if (!bResult) { | |
| 1188 m_status = FXCODEC_STATUS_ERR_READ; | |
| 1189 return FALSE; | |
| 1190 } | |
| 1191 m_offSet += size; | |
| 1192 pGifModule->Input(m_pGifContext, m_pSrcBuf, size); | |
| 1193 m_SrcComponents = 1; | |
| 1194 int32_t readResult = pGifModule->ReadHeader( | |
| 1195 m_pGifContext, &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber, | |
| 1196 (void**)&m_pGifPalette, &m_GifBgIndex, nullptr); | |
| 1197 while (readResult == 2) { | |
| 1198 FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; | |
| 1199 if (!GifReadMoreData(pGifModule, error_status)) { | |
| 1200 m_status = error_status; | |
| 1201 return FALSE; | |
| 1202 } | |
| 1203 readResult = pGifModule->ReadHeader( | |
| 1204 m_pGifContext, &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber, | |
| 1205 (void**)&m_pGifPalette, &m_GifBgIndex, nullptr); | |
| 1206 } | |
| 1207 if (readResult == 1) { | |
| 1208 m_SrcBPC = 8; | |
| 1209 m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); | |
| 1210 return TRUE; | |
| 1211 } | |
| 1212 if (m_pGifContext) { | |
| 1213 pGifModule->Finish(m_pGifContext); | |
| 1214 m_pGifContext = NULL; | |
| 1215 } | |
| 1216 m_status = FXCODEC_STATUS_ERR_FORMAT; | |
| 1217 return FALSE; | |
| 1218 } break; | |
| 1219 case FXCODEC_IMAGE_TIF: { | |
| 1220 ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); | |
| 1221 if (pTiffModule == NULL) { | |
| 1222 m_status = FXCODEC_STATUS_ERR_FORMAT; | |
| 1223 return FALSE; | |
| 1224 } | |
| 1225 m_pTiffContext = pTiffModule->CreateDecoder(m_pFile); | |
| 1226 if (m_pTiffContext == NULL) { | |
| 1227 m_status = FXCODEC_STATUS_ERR_FORMAT; | |
| 1228 return FALSE; | |
| 1229 } | |
| 1230 int32_t frames = 0; | |
| 1231 pTiffModule->GetFrames(m_pTiffContext, frames); | |
| 1232 FX_DWORD bpc; | |
| 1233 FX_BOOL ret = pTiffModule->LoadFrameInfo( | |
| 1234 m_pTiffContext, 0, (FX_DWORD&)m_SrcWidth, (FX_DWORD&)m_SrcHeight, | |
| 1235 (FX_DWORD&)m_SrcComponents, bpc, pAttribute); | |
| 1236 m_SrcComponents = 4; | |
| 1237 m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); | |
| 1238 if (!ret) { | |
| 1239 pTiffModule->DestroyDecoder(m_pTiffContext); | |
| 1240 (m_pTiffContext = NULL); | |
| 1241 (m_status = FXCODEC_STATUS_ERR_FORMAT); | |
| 1242 return FALSE; | |
| 1243 } | |
| 1244 } break; | |
| 1245 default: | |
| 1246 m_status = FXCODEC_STATUS_ERR_FORMAT; | |
| 1247 return FALSE; | |
| 1248 } | |
| 1249 return TRUE; | |
| 1250 } | |
| 1251 FXCODEC_STATUS CCodec_ProgressiveDecoder::LoadImageInfo( | |
| 1252 IFX_FileRead* pFile, | |
| 1253 FXCODEC_IMAGE_TYPE imageType, | |
| 1254 CFX_DIBAttribute* pAttribute) { | |
| 1255 switch (m_status) { | |
| 1256 case FXCODEC_STATUS_FRAME_READY: | |
| 1257 case FXCODEC_STATUS_FRAME_TOBECONTINUE: | |
| 1258 case FXCODEC_STATUS_DECODE_READY: | |
| 1259 case FXCODEC_STATUS_DECODE_TOBECONTINUE: | |
| 1260 return FXCODEC_STATUS_ERROR; | |
| 1261 default: | |
| 1262 break; | |
| 1263 } | |
| 1264 if (pFile == NULL) { | |
| 1265 m_status = FXCODEC_STATUS_ERR_PARAMS; | |
| 1266 m_pFile = NULL; | |
| 1267 return m_status; | |
| 1268 } | |
| 1269 m_pFile = pFile; | |
| 1270 m_offSet = 0; | |
| 1271 m_SrcWidth = m_SrcHeight = 0; | |
| 1272 m_SrcComponents = m_SrcBPC = 0; | |
| 1273 m_clipBox = FX_RECT(0, 0, 0, 0); | |
| 1274 m_startX = m_startY = 0; | |
| 1275 m_sizeX = m_sizeY = 0; | |
| 1276 m_SrcPassNumber = 0; | |
| 1277 if (imageType != FXCODEC_IMAGE_UNKNOWN && | |
| 1278 DetectImageType(imageType, pAttribute)) { | |
| 1279 m_imagType = imageType; | |
| 1280 m_status = FXCODEC_STATUS_FRAME_READY; | |
| 1281 return m_status; | |
| 1282 } | |
| 1283 for (int type = FXCODEC_IMAGE_BMP; type < FXCODEC_IMAGE_MAX; type++) { | |
| 1284 if (DetectImageType((FXCODEC_IMAGE_TYPE)type, pAttribute)) { | |
| 1285 m_imagType = (FXCODEC_IMAGE_TYPE)type; | |
| 1286 m_status = FXCODEC_STATUS_FRAME_READY; | |
| 1287 return m_status; | |
| 1288 } | |
| 1289 } | |
| 1290 m_status = FXCODEC_STATUS_ERR_FORMAT; | |
| 1291 m_pFile = NULL; | |
| 1292 return m_status; | |
| 1293 } | |
| 1294 void CCodec_ProgressiveDecoder::SetClipBox(FX_RECT* clip) { | |
| 1295 if (m_status != FXCODEC_STATUS_FRAME_READY) { | |
| 1296 return; | |
| 1297 } | |
| 1298 if (clip->IsEmpty()) { | |
| 1299 m_clipBox = FX_RECT(0, 0, 0, 0); | |
| 1300 return; | |
| 1301 } | |
| 1302 if (clip->left < 0) { | |
| 1303 clip->left = 0; | |
| 1304 } | |
| 1305 if (clip->right > m_SrcWidth) { | |
| 1306 clip->right = m_SrcWidth; | |
| 1307 } | |
| 1308 if (clip->top < 0) { | |
| 1309 clip->top = 0; | |
| 1310 } | |
| 1311 if (clip->bottom > m_SrcHeight) { | |
| 1312 clip->bottom = m_SrcHeight; | |
| 1313 } | |
| 1314 if (clip->IsEmpty()) { | |
| 1315 m_clipBox = FX_RECT(0, 0, 0, 0); | |
| 1316 return; | |
| 1317 } | |
| 1318 m_clipBox = *clip; | |
| 1319 } | |
| 1320 void CCodec_ProgressiveDecoder::GetDownScale(int& down_scale) { | |
| 1321 down_scale = 1; | |
| 1322 int ratio_w = m_clipBox.Width() / m_sizeX; | |
| 1323 int ratio_h = m_clipBox.Height() / m_sizeY; | |
| 1324 int ratio = (ratio_w > ratio_h) ? ratio_h : ratio_w; | |
| 1325 if (ratio >= 8) { | |
| 1326 down_scale = 8; | |
| 1327 } else if (ratio >= 4) { | |
| 1328 down_scale = 4; | |
| 1329 } else if (ratio >= 2) { | |
| 1330 down_scale = 2; | |
| 1331 } | |
| 1332 m_clipBox.left /= down_scale; | |
| 1333 m_clipBox.right /= down_scale; | |
| 1334 m_clipBox.top /= down_scale; | |
| 1335 m_clipBox.bottom /= down_scale; | |
| 1336 if (m_clipBox.right == m_clipBox.left) { | |
| 1337 m_clipBox.right = m_clipBox.left + 1; | |
| 1338 } | |
| 1339 if (m_clipBox.bottom == m_clipBox.top) { | |
| 1340 m_clipBox.bottom = m_clipBox.top + 1; | |
| 1341 } | |
| 1342 } | |
| 1343 void CCodec_ProgressiveDecoder::GetTransMethod(FXDIB_Format des_format, | |
| 1344 FXCodec_Format src_format) { | |
| 1345 switch (des_format) { | |
| 1346 case FXDIB_1bppMask: | |
| 1347 case FXDIB_1bppRgb: { | |
| 1348 switch (src_format) { | |
| 1349 case FXCodec_1bppGray: | |
| 1350 m_TransMethod = 0; | |
| 1351 break; | |
| 1352 default: | |
| 1353 m_TransMethod = -1; | |
| 1354 } | |
| 1355 } break; | |
| 1356 case FXDIB_8bppMask: | |
| 1357 case FXDIB_8bppRgb: { | |
| 1358 switch (src_format) { | |
| 1359 case FXCodec_1bppGray: | |
| 1360 m_TransMethod = 1; | |
| 1361 break; | |
| 1362 case FXCodec_8bppGray: | |
| 1363 m_TransMethod = 2; | |
| 1364 break; | |
| 1365 case FXCodec_1bppRgb: | |
| 1366 case FXCodec_8bppRgb: | |
| 1367 m_TransMethod = 3; | |
| 1368 break; | |
| 1369 case FXCodec_Rgb: | |
| 1370 case FXCodec_Rgb32: | |
| 1371 case FXCodec_Argb: | |
| 1372 m_TransMethod = 4; | |
| 1373 break; | |
| 1374 case FXCodec_Cmyk: | |
| 1375 m_TransMethod = 5; | |
| 1376 break; | |
| 1377 default: | |
| 1378 m_TransMethod = -1; | |
| 1379 } | |
| 1380 } break; | |
| 1381 case FXDIB_Rgb: { | |
| 1382 switch (src_format) { | |
| 1383 case FXCodec_1bppGray: | |
| 1384 m_TransMethod = 6; | |
| 1385 break; | |
| 1386 case FXCodec_8bppGray: | |
| 1387 m_TransMethod = 7; | |
| 1388 break; | |
| 1389 case FXCodec_1bppRgb: | |
| 1390 case FXCodec_8bppRgb: | |
| 1391 m_TransMethod = 8; | |
| 1392 break; | |
| 1393 case FXCodec_Rgb: | |
| 1394 case FXCodec_Rgb32: | |
| 1395 case FXCodec_Argb: | |
| 1396 m_TransMethod = 9; | |
| 1397 break; | |
| 1398 case FXCodec_Cmyk: | |
| 1399 m_TransMethod = 10; | |
| 1400 break; | |
| 1401 default: | |
| 1402 m_TransMethod = -1; | |
| 1403 } | |
| 1404 } break; | |
| 1405 case FXDIB_Rgb32: | |
| 1406 case FXDIB_Argb: { | |
| 1407 switch (src_format) { | |
| 1408 case FXCodec_1bppGray: | |
| 1409 m_TransMethod = 6; | |
| 1410 break; | |
| 1411 case FXCodec_8bppGray: | |
| 1412 m_TransMethod = 7; | |
| 1413 break; | |
| 1414 case FXCodec_1bppRgb: | |
| 1415 case FXCodec_8bppRgb: | |
| 1416 if (des_format == FXDIB_Argb) { | |
| 1417 m_TransMethod = 12; | |
| 1418 } else { | |
| 1419 m_TransMethod = 8; | |
| 1420 } | |
| 1421 break; | |
| 1422 case FXCodec_Rgb: | |
| 1423 case FXCodec_Rgb32: | |
| 1424 m_TransMethod = 9; | |
| 1425 break; | |
| 1426 case FXCodec_Cmyk: | |
| 1427 m_TransMethod = 10; | |
| 1428 break; | |
| 1429 case FXCodec_Argb: | |
| 1430 m_TransMethod = 11; | |
| 1431 break; | |
| 1432 default: | |
| 1433 m_TransMethod = -1; | |
| 1434 } | |
| 1435 } break; | |
| 1436 default: | |
| 1437 m_TransMethod = -1; | |
| 1438 } | |
| 1439 } | |
| 1440 void _RGB2BGR(uint8_t* buffer, int width = 1) { | |
| 1441 if (buffer && width > 0) { | |
| 1442 uint8_t temp; | |
| 1443 int i = 0; | |
| 1444 int j = 0; | |
| 1445 for (; i < width; i++, j += 3) { | |
| 1446 temp = buffer[j]; | |
| 1447 buffer[j] = buffer[j + 2]; | |
| 1448 buffer[j + 2] = temp; | |
| 1449 } | |
| 1450 } | |
| 1451 } | |
| 1452 void CCodec_ProgressiveDecoder::ReSampleScanline(CFX_DIBitmap* pDeviceBitmap, | |
| 1453 int des_line, | |
| 1454 uint8_t* src_scan, | |
| 1455 FXCodec_Format src_format) { | |
| 1456 int src_left = m_clipBox.left; | |
| 1457 int des_left = m_startX; | |
| 1458 uint8_t* des_scan = | |
| 1459 pDeviceBitmap->GetBuffer() + des_line * pDeviceBitmap->GetPitch(); | |
| 1460 int src_bpp = src_format & 0xff; | |
| 1461 int des_bpp = pDeviceBitmap->GetBPP(); | |
| 1462 int src_Bpp = src_bpp >> 3; | |
| 1463 int des_Bpp = des_bpp >> 3; | |
| 1464 src_scan += src_left * src_Bpp; | |
| 1465 des_scan += des_left * des_Bpp; | |
| 1466 for (int des_col = 0; des_col < m_sizeX; des_col++) { | |
| 1467 PixelWeight* pPixelWeights = m_WeightHorz.GetPixelWeight(des_col); | |
| 1468 switch (m_TransMethod) { | |
| 1469 case -1: | |
| 1470 return; | |
| 1471 case 0: | |
| 1472 return; | |
| 1473 case 1: | |
| 1474 return; | |
| 1475 case 2: { | |
| 1476 FX_DWORD des_g = 0; | |
| 1477 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | |
| 1478 j++) { | |
| 1479 int pixel_weight = | |
| 1480 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | |
| 1481 des_g += pixel_weight * src_scan[j]; | |
| 1482 } | |
| 1483 *des_scan++ = (uint8_t)(des_g >> 16); | |
| 1484 } break; | |
| 1485 case 3: { | |
| 1486 int des_r = 0, des_g = 0, des_b = 0; | |
| 1487 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | |
| 1488 j++) { | |
| 1489 int pixel_weight = | |
| 1490 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | |
| 1491 unsigned long argb = m_pSrcPalette[src_scan[j]]; | |
| 1492 des_r += pixel_weight * (uint8_t)(argb >> 16); | |
| 1493 des_g += pixel_weight * (uint8_t)(argb >> 8); | |
| 1494 des_b += pixel_weight * (uint8_t)argb; | |
| 1495 } | |
| 1496 *des_scan++ = | |
| 1497 (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); | |
| 1498 } break; | |
| 1499 case 4: { | |
| 1500 FX_DWORD des_b = 0, des_g = 0, des_r = 0; | |
| 1501 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | |
| 1502 j++) { | |
| 1503 int pixel_weight = | |
| 1504 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | |
| 1505 const uint8_t* src_pixel = src_scan + j * src_Bpp; | |
| 1506 des_b += pixel_weight * (*src_pixel++); | |
| 1507 des_g += pixel_weight * (*src_pixel++); | |
| 1508 des_r += pixel_weight * (*src_pixel); | |
| 1509 } | |
| 1510 *des_scan++ = | |
| 1511 (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); | |
| 1512 } break; | |
| 1513 case 5: { | |
| 1514 FX_DWORD des_b = 0, des_g = 0, des_r = 0; | |
| 1515 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | |
| 1516 j++) { | |
| 1517 int pixel_weight = | |
| 1518 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | |
| 1519 const uint8_t* src_pixel = src_scan + j * src_Bpp; | |
| 1520 uint8_t src_b = 0, src_g = 0, src_r = 0; | |
| 1521 AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], | |
| 1522 255 - src_pixel[2], 255 - src_pixel[3], src_r, | |
| 1523 src_g, src_b); | |
| 1524 des_b += pixel_weight * src_b; | |
| 1525 des_g += pixel_weight * src_g; | |
| 1526 des_r += pixel_weight * src_r; | |
| 1527 } | |
| 1528 *des_scan++ = | |
| 1529 (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); | |
| 1530 } break; | |
| 1531 case 6: | |
| 1532 return; | |
| 1533 case 7: { | |
| 1534 FX_DWORD des_g = 0; | |
| 1535 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | |
| 1536 j++) { | |
| 1537 int pixel_weight = | |
| 1538 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | |
| 1539 des_g += pixel_weight * src_scan[j]; | |
| 1540 } | |
| 1541 FXSYS_memset(des_scan, (uint8_t)(des_g >> 16), 3); | |
| 1542 des_scan += des_Bpp; | |
| 1543 } break; | |
| 1544 case 8: { | |
| 1545 int des_r = 0, des_g = 0, des_b = 0; | |
| 1546 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | |
| 1547 j++) { | |
| 1548 int pixel_weight = | |
| 1549 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | |
| 1550 unsigned long argb = m_pSrcPalette[src_scan[j]]; | |
| 1551 des_r += pixel_weight * (uint8_t)(argb >> 16); | |
| 1552 des_g += pixel_weight * (uint8_t)(argb >> 8); | |
| 1553 des_b += pixel_weight * (uint8_t)argb; | |
| 1554 } | |
| 1555 *des_scan++ = (uint8_t)((des_b) >> 16); | |
| 1556 *des_scan++ = (uint8_t)((des_g) >> 16); | |
| 1557 *des_scan++ = (uint8_t)((des_r) >> 16); | |
| 1558 des_scan += des_Bpp - 3; | |
| 1559 } break; | |
| 1560 case 12: { | |
| 1561 if (m_pBmpContext) { | |
| 1562 int des_r = 0, des_g = 0, des_b = 0; | |
| 1563 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | |
| 1564 j++) { | |
| 1565 int pixel_weight = | |
| 1566 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | |
| 1567 unsigned long argb = m_pSrcPalette[src_scan[j]]; | |
| 1568 des_r += pixel_weight * (uint8_t)(argb >> 16); | |
| 1569 des_g += pixel_weight * (uint8_t)(argb >> 8); | |
| 1570 des_b += pixel_weight * (uint8_t)argb; | |
| 1571 } | |
| 1572 *des_scan++ = (uint8_t)((des_b) >> 16); | |
| 1573 *des_scan++ = (uint8_t)((des_g) >> 16); | |
| 1574 *des_scan++ = (uint8_t)((des_r) >> 16); | |
| 1575 *des_scan++ = 0xFF; | |
| 1576 } else { | |
| 1577 int des_a = 0, des_r = 0, des_g = 0, des_b = 0; | |
| 1578 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | |
| 1579 j++) { | |
| 1580 int pixel_weight = | |
| 1581 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | |
| 1582 unsigned long argb = m_pSrcPalette[src_scan[j]]; | |
| 1583 des_a += pixel_weight * (uint8_t)(argb >> 24); | |
| 1584 des_r += pixel_weight * (uint8_t)(argb >> 16); | |
| 1585 des_g += pixel_weight * (uint8_t)(argb >> 8); | |
| 1586 des_b += pixel_weight * (uint8_t)argb; | |
| 1587 } | |
| 1588 *des_scan++ = (uint8_t)((des_b) >> 16); | |
| 1589 *des_scan++ = (uint8_t)((des_g) >> 16); | |
| 1590 *des_scan++ = (uint8_t)((des_r) >> 16); | |
| 1591 *des_scan++ = (uint8_t)((des_a) >> 16); | |
| 1592 } | |
| 1593 } break; | |
| 1594 case 9: { | |
| 1595 FX_DWORD des_b = 0, des_g = 0, des_r = 0; | |
| 1596 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | |
| 1597 j++) { | |
| 1598 int pixel_weight = | |
| 1599 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | |
| 1600 const uint8_t* src_pixel = src_scan + j * src_Bpp; | |
| 1601 des_b += pixel_weight * (*src_pixel++); | |
| 1602 des_g += pixel_weight * (*src_pixel++); | |
| 1603 des_r += pixel_weight * (*src_pixel); | |
| 1604 } | |
| 1605 *des_scan++ = (uint8_t)((des_b) >> 16); | |
| 1606 *des_scan++ = (uint8_t)((des_g) >> 16); | |
| 1607 *des_scan++ = (uint8_t)((des_r) >> 16); | |
| 1608 des_scan += des_Bpp - 3; | |
| 1609 } break; | |
| 1610 case 10: { | |
| 1611 FX_DWORD des_b = 0, des_g = 0, des_r = 0; | |
| 1612 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | |
| 1613 j++) { | |
| 1614 int pixel_weight = | |
| 1615 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | |
| 1616 const uint8_t* src_pixel = src_scan + j * src_Bpp; | |
| 1617 uint8_t src_b = 0, src_g = 0, src_r = 0; | |
| 1618 AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], | |
| 1619 255 - src_pixel[2], 255 - src_pixel[3], src_r, | |
| 1620 src_g, src_b); | |
| 1621 des_b += pixel_weight * src_b; | |
| 1622 des_g += pixel_weight * src_g; | |
| 1623 des_r += pixel_weight * src_r; | |
| 1624 } | |
| 1625 *des_scan++ = (uint8_t)((des_b) >> 16); | |
| 1626 *des_scan++ = (uint8_t)((des_g) >> 16); | |
| 1627 *des_scan++ = (uint8_t)((des_r) >> 16); | |
| 1628 des_scan += des_Bpp - 3; | |
| 1629 } break; | |
| 1630 case 11: { | |
| 1631 FX_DWORD des_alpha = 0, des_r = 0, des_g = 0, des_b = 0; | |
| 1632 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | |
| 1633 j++) { | |
| 1634 int pixel_weight = | |
| 1635 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | |
| 1636 const uint8_t* src_pixel = src_scan + j * src_Bpp; | |
| 1637 pixel_weight = pixel_weight * src_pixel[3] / 255; | |
| 1638 des_b += pixel_weight * (*src_pixel++); | |
| 1639 des_g += pixel_weight * (*src_pixel++); | |
| 1640 des_r += pixel_weight * (*src_pixel); | |
| 1641 des_alpha += pixel_weight; | |
| 1642 } | |
| 1643 *des_scan++ = (uint8_t)((des_b) >> 16); | |
| 1644 *des_scan++ = (uint8_t)((des_g) >> 16); | |
| 1645 *des_scan++ = (uint8_t)((des_r) >> 16); | |
| 1646 *des_scan++ = (uint8_t)((des_alpha * 255) >> 16); | |
| 1647 } break; | |
| 1648 default: | |
| 1649 return; | |
| 1650 } | |
| 1651 } | |
| 1652 } | |
| 1653 void CCodec_ProgressiveDecoder::ResampleVert(CFX_DIBitmap* pDeviceBitmap, | |
| 1654 double scale_y, | |
| 1655 int des_row) { | |
| 1656 int des_Bpp = pDeviceBitmap->GetBPP() >> 3; | |
| 1657 FX_DWORD des_ScanOffet = m_startX * des_Bpp; | |
| 1658 if (m_bInterpol) { | |
| 1659 int des_top = m_startY; | |
| 1660 int des_row_1 = des_row - int(scale_y); | |
| 1661 if (des_row_1 < des_top) { | |
| 1662 int des_bottom = des_top + m_sizeY; | |
| 1663 if (des_row + (int)scale_y >= des_bottom - 1) { | |
| 1664 uint8_t* scan_src = | |
| 1665 (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; | |
| 1666 while (++des_row < des_bottom) { | |
| 1667 uint8_t* scan_des = | |
| 1668 (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; | |
| 1669 FX_DWORD size = m_sizeX * des_Bpp; | |
| 1670 FXSYS_memcpy(scan_des, scan_src, size); | |
| 1671 } | |
| 1672 } | |
| 1673 return; | |
| 1674 } | |
| 1675 for (; des_row_1 < des_row; des_row_1++) { | |
| 1676 uint8_t* scan_des = | |
| 1677 (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; | |
| 1678 PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); | |
| 1679 const uint8_t* scan_src1 = | |
| 1680 pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + | |
| 1681 des_ScanOffet; | |
| 1682 const uint8_t* scan_src2 = | |
| 1683 pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + | |
| 1684 des_ScanOffet; | |
| 1685 for (int des_col = 0; des_col < m_sizeX; des_col++) { | |
| 1686 switch (pDeviceBitmap->GetFormat()) { | |
| 1687 case FXDIB_Invalid: | |
| 1688 case FXDIB_1bppMask: | |
| 1689 case FXDIB_1bppRgb: | |
| 1690 return; | |
| 1691 case FXDIB_8bppMask: | |
| 1692 case FXDIB_8bppRgb: { | |
| 1693 if (pDeviceBitmap->GetPalette()) { | |
| 1694 return; | |
| 1695 } | |
| 1696 int des_g = 0; | |
| 1697 des_g += pWeight->m_Weights[0] * (*scan_src1++); | |
| 1698 des_g += pWeight->m_Weights[1] * (*scan_src2++); | |
| 1699 *scan_des++ = (uint8_t)(des_g >> 16); | |
| 1700 } break; | |
| 1701 case FXDIB_Rgb: | |
| 1702 case FXDIB_Rgb32: { | |
| 1703 FX_DWORD des_b = 0, des_g = 0, des_r = 0; | |
| 1704 des_b += pWeight->m_Weights[0] * (*scan_src1++); | |
| 1705 des_g += pWeight->m_Weights[0] * (*scan_src1++); | |
| 1706 des_r += pWeight->m_Weights[0] * (*scan_src1++); | |
| 1707 scan_src1 += des_Bpp - 3; | |
| 1708 des_b += pWeight->m_Weights[1] * (*scan_src2++); | |
| 1709 des_g += pWeight->m_Weights[1] * (*scan_src2++); | |
| 1710 des_r += pWeight->m_Weights[1] * (*scan_src2++); | |
| 1711 scan_src2 += des_Bpp - 3; | |
| 1712 *scan_des++ = (uint8_t)((des_b) >> 16); | |
| 1713 *scan_des++ = (uint8_t)((des_g) >> 16); | |
| 1714 *scan_des++ = (uint8_t)((des_r) >> 16); | |
| 1715 scan_des += des_Bpp - 3; | |
| 1716 } break; | |
| 1717 case FXDIB_Argb: { | |
| 1718 FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; | |
| 1719 des_b += pWeight->m_Weights[0] * (*scan_src1++); | |
| 1720 des_g += pWeight->m_Weights[0] * (*scan_src1++); | |
| 1721 des_r += pWeight->m_Weights[0] * (*scan_src1++); | |
| 1722 des_a += pWeight->m_Weights[0] * (*scan_src1++); | |
| 1723 des_b += pWeight->m_Weights[1] * (*scan_src2++); | |
| 1724 des_g += pWeight->m_Weights[1] * (*scan_src2++); | |
| 1725 des_r += pWeight->m_Weights[1] * (*scan_src2++); | |
| 1726 des_a += pWeight->m_Weights[1] * (*scan_src2++); | |
| 1727 *scan_des++ = (uint8_t)((des_b) >> 16); | |
| 1728 *scan_des++ = (uint8_t)((des_g) >> 16); | |
| 1729 *scan_des++ = (uint8_t)((des_r) >> 16); | |
| 1730 *scan_des++ = (uint8_t)((des_a) >> 16); | |
| 1731 } break; | |
| 1732 default: | |
| 1733 return; | |
| 1734 } | |
| 1735 } | |
| 1736 } | |
| 1737 int des_bottom = des_top + m_sizeY; | |
| 1738 if (des_row + (int)scale_y >= des_bottom - 1) { | |
| 1739 uint8_t* scan_src = | |
| 1740 (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; | |
| 1741 while (++des_row < des_bottom) { | |
| 1742 uint8_t* scan_des = | |
| 1743 (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; | |
| 1744 FX_DWORD size = m_sizeX * des_Bpp; | |
| 1745 FXSYS_memcpy(scan_des, scan_src, size); | |
| 1746 } | |
| 1747 } | |
| 1748 return; | |
| 1749 } | |
| 1750 int multiple = (int)FXSYS_ceil((FX_FLOAT)scale_y - 1); | |
| 1751 if (multiple > 0) { | |
| 1752 uint8_t* scan_src = | |
| 1753 (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; | |
| 1754 for (int i = 1; i <= multiple; i++) { | |
| 1755 if (des_row + i >= m_startY + m_sizeY) { | |
| 1756 return; | |
| 1757 } | |
| 1758 uint8_t* scan_des = | |
| 1759 (uint8_t*)pDeviceBitmap->GetScanline(des_row + i) + des_ScanOffet; | |
| 1760 FX_DWORD size = m_sizeX * des_Bpp; | |
| 1761 FXSYS_memcpy(scan_des, scan_src, size); | |
| 1762 } | |
| 1763 } | |
| 1764 } | |
| 1765 void CCodec_ProgressiveDecoder::Resample(CFX_DIBitmap* pDeviceBitmap, | |
| 1766 int32_t src_line, | |
| 1767 uint8_t* src_scan, | |
| 1768 FXCodec_Format src_format) { | |
| 1769 int src_top = m_clipBox.top; | |
| 1770 int des_top = m_startY; | |
| 1771 int src_hei = m_clipBox.Height(); | |
| 1772 int des_hei = m_sizeY; | |
| 1773 if (src_line >= src_top) { | |
| 1774 double scale_y = (double)des_hei / (double)src_hei; | |
| 1775 int src_row = src_line - src_top; | |
| 1776 int des_row = (int)(src_row * scale_y) + des_top; | |
| 1777 if (des_row >= des_top + des_hei) { | |
| 1778 return; | |
| 1779 } | |
| 1780 ReSampleScanline(pDeviceBitmap, des_row, m_pDecodeBuf, src_format); | |
| 1781 if (scale_y > 1.0) { | |
| 1782 ResampleVert(pDeviceBitmap, scale_y, des_row); | |
| 1783 } | |
| 1784 } | |
| 1785 } | |
| 1786 FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames, | |
| 1787 IFX_Pause* pPause) { | |
| 1788 if (!(m_status == FXCODEC_STATUS_FRAME_READY || | |
| 1789 m_status == FXCODEC_STATUS_FRAME_TOBECONTINUE)) { | |
| 1790 return FXCODEC_STATUS_ERROR; | |
| 1791 } | |
| 1792 switch (m_imagType) { | |
| 1793 case FXCODEC_IMAGE_BMP: | |
| 1794 case FXCODEC_IMAGE_JPG: | |
| 1795 case FXCODEC_IMAGE_PNG: | |
| 1796 case FXCODEC_IMAGE_TIF: | |
| 1797 frames = m_FrameNumber = 1; | |
| 1798 return m_status = FXCODEC_STATUS_DECODE_READY; | |
| 1799 case FXCODEC_IMAGE_GIF: { | |
| 1800 ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); | |
| 1801 while (TRUE) { | |
| 1802 int32_t readResult = | |
| 1803 pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber); | |
| 1804 while (readResult == 2) { | |
| 1805 FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_READ; | |
| 1806 if (!GifReadMoreData(pGifModule, error_status)) { | |
| 1807 return error_status; | |
| 1808 } | |
| 1809 if (pPause && pPause->NeedToPauseNow()) { | |
| 1810 return m_status = FXCODEC_STATUS_FRAME_TOBECONTINUE; | |
| 1811 } | |
| 1812 readResult = pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber); | |
| 1813 } | |
| 1814 if (readResult == 1) { | |
| 1815 frames = m_FrameNumber; | |
| 1816 return m_status = FXCODEC_STATUS_DECODE_READY; | |
| 1817 } | |
| 1818 if (m_pGifContext) { | |
| 1819 pGifModule->Finish(m_pGifContext); | |
| 1820 m_pGifContext = NULL; | |
| 1821 } | |
| 1822 return m_status = FXCODEC_STATUS_ERROR; | |
| 1823 } | |
| 1824 } break; | |
| 1825 default: | |
| 1826 break; | |
| 1827 } | |
| 1828 return FXCODEC_STATUS_ERROR; | |
| 1829 } | |
| 1830 FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap, | |
| 1831 int start_x, | |
| 1832 int start_y, | |
| 1833 int size_x, | |
| 1834 int size_y, | |
| 1835 int32_t frames, | |
| 1836 FX_BOOL bInterpol) { | |
| 1837 if (m_status != FXCODEC_STATUS_DECODE_READY) { | |
| 1838 return FXCODEC_STATUS_ERROR; | |
| 1839 } | |
| 1840 if (pDIBitmap == NULL || pDIBitmap->GetBPP() < 8 || frames < 0 || | |
| 1841 frames >= m_FrameNumber) { | |
| 1842 return FXCODEC_STATUS_ERR_PARAMS; | |
| 1843 } | |
| 1844 m_pDeviceBitmap = pDIBitmap; | |
| 1845 if (m_clipBox.IsEmpty()) { | |
| 1846 return FXCODEC_STATUS_ERR_PARAMS; | |
| 1847 } | |
| 1848 if (size_x <= 0 || size_x > 65535 || size_y <= 0 || size_y > 65535) { | |
| 1849 return FXCODEC_STATUS_ERR_PARAMS; | |
| 1850 } | |
| 1851 FX_RECT device_rc = | |
| 1852 FX_RECT(start_x, start_y, start_x + size_x, start_y + size_y); | |
| 1853 int32_t out_range_x = device_rc.right - pDIBitmap->GetWidth(); | |
| 1854 int32_t out_range_y = device_rc.bottom - pDIBitmap->GetHeight(); | |
| 1855 device_rc.Intersect( | |
| 1856 FX_RECT(0, 0, pDIBitmap->GetWidth(), pDIBitmap->GetHeight())); | |
| 1857 if (device_rc.IsEmpty()) { | |
| 1858 return FXCODEC_STATUS_ERR_PARAMS; | |
| 1859 } | |
| 1860 m_startX = device_rc.left; | |
| 1861 m_startY = device_rc.top; | |
| 1862 m_sizeX = device_rc.Width(); | |
| 1863 m_sizeY = device_rc.Height(); | |
| 1864 m_bInterpol = bInterpol; | |
| 1865 m_FrameCur = 0; | |
| 1866 if (start_x < 0 || out_range_x > 0) { | |
| 1867 FX_FLOAT scaleX = (FX_FLOAT)m_clipBox.Width() / (FX_FLOAT)size_x; | |
| 1868 if (start_x < 0) { | |
| 1869 m_clipBox.left -= (int32_t)FXSYS_ceil((FX_FLOAT)start_x * scaleX); | |
| 1870 } | |
| 1871 if (out_range_x > 0) { | |
| 1872 m_clipBox.right -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_x * scaleX); | |
| 1873 } | |
| 1874 } | |
| 1875 if (start_y < 0 || out_range_y > 0) { | |
| 1876 FX_FLOAT scaleY = (FX_FLOAT)m_clipBox.Height() / (FX_FLOAT)size_y; | |
| 1877 if (start_y < 0) { | |
| 1878 m_clipBox.top -= (int32_t)FXSYS_ceil((FX_FLOAT)start_y * scaleY); | |
| 1879 } | |
| 1880 if (out_range_y > 0) { | |
| 1881 m_clipBox.bottom -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_y * scaleY); | |
| 1882 } | |
| 1883 } | |
| 1884 if (m_clipBox.IsEmpty()) { | |
| 1885 return FXCODEC_STATUS_ERR_PARAMS; | |
| 1886 } | |
| 1887 switch (m_imagType) { | |
| 1888 case FXCODEC_IMAGE_JPG: { | |
| 1889 ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); | |
| 1890 int down_scale = 1; | |
| 1891 GetDownScale(down_scale); | |
| 1892 FX_BOOL bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale); | |
| 1893 while (!bStart) { | |
| 1894 FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; | |
| 1895 if (!JpegReadMoreData(pJpegModule, error_status)) { | |
| 1896 m_pDeviceBitmap = NULL; | |
| 1897 m_pFile = NULL; | |
| 1898 return m_status = error_status; | |
| 1899 } | |
| 1900 bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale); | |
| 1901 } | |
| 1902 int scanline_size = (m_SrcWidth + down_scale - 1) / down_scale; | |
| 1903 scanline_size = (scanline_size * m_SrcComponents + 3) / 4 * 4; | |
| 1904 FX_Free(m_pDecodeBuf); | |
| 1905 m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); | |
| 1906 FXSYS_memset(m_pDecodeBuf, 0, scanline_size); | |
| 1907 m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, | |
| 1908 m_clipBox.Width(), m_bInterpol); | |
| 1909 m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); | |
| 1910 switch (m_SrcComponents) { | |
| 1911 case 1: | |
| 1912 m_SrcFormat = FXCodec_8bppGray; | |
| 1913 break; | |
| 1914 case 3: | |
| 1915 m_SrcFormat = FXCodec_Rgb; | |
| 1916 break; | |
| 1917 case 4: | |
| 1918 m_SrcFormat = FXCodec_Cmyk; | |
| 1919 break; | |
| 1920 } | |
| 1921 GetTransMethod(pDIBitmap->GetFormat(), m_SrcFormat); | |
| 1922 return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 1923 } break; | |
| 1924 case FXCODEC_IMAGE_PNG: { | |
| 1925 ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); | |
| 1926 if (pPngModule == NULL) { | |
| 1927 m_pDeviceBitmap = NULL; | |
| 1928 m_pFile = NULL; | |
| 1929 return m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 1930 } | |
| 1931 if (m_pPngContext) { | |
| 1932 pPngModule->Finish(m_pPngContext); | |
| 1933 m_pPngContext = NULL; | |
| 1934 } | |
| 1935 m_pPngContext = pPngModule->Start((void*)this); | |
| 1936 if (m_pPngContext == NULL) { | |
| 1937 m_pDeviceBitmap = NULL; | |
| 1938 m_pFile = NULL; | |
| 1939 return m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 1940 } | |
| 1941 m_offSet = 0; | |
| 1942 switch (m_pDeviceBitmap->GetFormat()) { | |
| 1943 case FXDIB_8bppMask: | |
| 1944 case FXDIB_8bppRgb: | |
| 1945 m_SrcComponents = 1; | |
| 1946 m_SrcFormat = FXCodec_8bppGray; | |
| 1947 break; | |
| 1948 case FXDIB_Rgb: | |
| 1949 m_SrcComponents = 3; | |
| 1950 m_SrcFormat = FXCodec_Rgb; | |
| 1951 break; | |
| 1952 case FXDIB_Rgb32: | |
| 1953 case FXDIB_Argb: | |
| 1954 m_SrcComponents = 4; | |
| 1955 m_SrcFormat = FXCodec_Argb; | |
| 1956 break; | |
| 1957 default: { | |
| 1958 m_pDeviceBitmap = NULL; | |
| 1959 m_pFile = NULL; | |
| 1960 return m_status = FXCODEC_STATUS_ERR_PARAMS; | |
| 1961 } | |
| 1962 } | |
| 1963 GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); | |
| 1964 int scanline_size = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4; | |
| 1965 FX_Free(m_pDecodeBuf); | |
| 1966 m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); | |
| 1967 FXSYS_memset(m_pDecodeBuf, 0, scanline_size); | |
| 1968 m_WeightHorzOO.Calc(m_sizeX, m_clipBox.Width(), m_bInterpol); | |
| 1969 m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); | |
| 1970 return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 1971 } break; | |
| 1972 case FXCODEC_IMAGE_GIF: { | |
| 1973 ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); | |
| 1974 if (pGifModule == NULL) { | |
| 1975 m_pDeviceBitmap = NULL; | |
| 1976 m_pFile = NULL; | |
| 1977 return m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 1978 } | |
| 1979 m_SrcFormat = FXCodec_8bppRgb; | |
| 1980 GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); | |
| 1981 int scanline_size = (m_SrcWidth + 3) / 4 * 4; | |
| 1982 FX_Free(m_pDecodeBuf); | |
| 1983 m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); | |
| 1984 FXSYS_memset(m_pDecodeBuf, 0, scanline_size); | |
| 1985 m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, | |
| 1986 m_clipBox.Width(), m_bInterpol); | |
| 1987 m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); | |
| 1988 m_FrameCur = frames; | |
| 1989 return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 1990 } break; | |
| 1991 case FXCODEC_IMAGE_BMP: { | |
| 1992 ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); | |
| 1993 if (pBmpModule == NULL) { | |
| 1994 m_pDeviceBitmap = NULL; | |
| 1995 m_pFile = NULL; | |
| 1996 return m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 1997 } | |
| 1998 switch (m_SrcComponents) { | |
| 1999 case 1: | |
| 2000 m_SrcFormat = FXCodec_8bppRgb; | |
| 2001 break; | |
| 2002 case 3: | |
| 2003 m_SrcFormat = FXCodec_Rgb; | |
| 2004 break; | |
| 2005 case 4: | |
| 2006 m_SrcFormat = FXCodec_Rgb32; | |
| 2007 break; | |
| 2008 } | |
| 2009 GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); | |
| 2010 m_ScanlineSize = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4; | |
| 2011 FX_Free(m_pDecodeBuf); | |
| 2012 m_pDecodeBuf = FX_Alloc(uint8_t, m_ScanlineSize); | |
| 2013 FXSYS_memset(m_pDecodeBuf, 0, m_ScanlineSize); | |
| 2014 m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, | |
| 2015 m_clipBox.Width(), m_bInterpol); | |
| 2016 m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); | |
| 2017 return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 2018 } break; | |
| 2019 case FXCODEC_IMAGE_TIF: | |
| 2020 return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 2021 default: | |
| 2022 break; | |
| 2023 } | |
| 2024 return FXCODEC_STATUS_ERROR; | |
| 2025 } | |
| 2026 FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { | |
| 2027 if (m_status != FXCODEC_STATUS_DECODE_TOBECONTINUE) { | |
| 2028 return FXCODEC_STATUS_ERROR; | |
| 2029 } | |
| 2030 switch (m_imagType) { | |
| 2031 case FXCODEC_IMAGE_JPG: { | |
| 2032 ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); | |
| 2033 while (TRUE) { | |
| 2034 FX_BOOL readRes = | |
| 2035 pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf); | |
| 2036 while (!readRes) { | |
| 2037 FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; | |
| 2038 if (!JpegReadMoreData(pJpegModule, error_status)) { | |
| 2039 m_pDeviceBitmap = NULL; | |
| 2040 m_pFile = NULL; | |
| 2041 return m_status = error_status; | |
| 2042 } | |
| 2043 readRes = pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf); | |
| 2044 } | |
| 2045 if (m_SrcFormat == FXCodec_Rgb) { | |
| 2046 int src_Bpp = (m_SrcFormat & 0xff) >> 3; | |
| 2047 _RGB2BGR(m_pDecodeBuf + m_clipBox.left * src_Bpp, m_clipBox.Width()); | |
| 2048 } | |
| 2049 if (m_SrcRow >= m_clipBox.bottom) { | |
| 2050 m_pDeviceBitmap = NULL; | |
| 2051 m_pFile = NULL; | |
| 2052 return m_status = FXCODEC_STATUS_DECODE_FINISH; | |
| 2053 } | |
| 2054 Resample(m_pDeviceBitmap, m_SrcRow, m_pDecodeBuf, m_SrcFormat); | |
| 2055 m_SrcRow++; | |
| 2056 if (pPause && pPause->NeedToPauseNow()) { | |
| 2057 return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 2058 } | |
| 2059 } | |
| 2060 } break; | |
| 2061 case FXCODEC_IMAGE_PNG: { | |
| 2062 ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); | |
| 2063 while (TRUE) { | |
| 2064 FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet; | |
| 2065 FX_DWORD input_size = | |
| 2066 remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size; | |
| 2067 if (input_size == 0) { | |
| 2068 if (m_pPngContext) { | |
| 2069 pPngModule->Finish(m_pPngContext); | |
| 2070 } | |
| 2071 m_pPngContext = NULL; | |
| 2072 m_pDeviceBitmap = NULL; | |
| 2073 m_pFile = NULL; | |
| 2074 return m_status = FXCODEC_STATUS_DECODE_FINISH; | |
| 2075 } | |
| 2076 if (m_pSrcBuf && input_size > m_SrcSize) { | |
| 2077 FX_Free(m_pSrcBuf); | |
| 2078 m_pSrcBuf = FX_Alloc(uint8_t, input_size); | |
| 2079 FXSYS_memset(m_pSrcBuf, 0, input_size); | |
| 2080 m_SrcSize = input_size; | |
| 2081 } | |
| 2082 FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size); | |
| 2083 if (!bResult) { | |
| 2084 m_pDeviceBitmap = NULL; | |
| 2085 m_pFile = NULL; | |
| 2086 return m_status = FXCODEC_STATUS_ERR_READ; | |
| 2087 } | |
| 2088 m_offSet += input_size; | |
| 2089 bResult = | |
| 2090 pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, nullptr); | |
| 2091 if (!bResult) { | |
| 2092 m_pDeviceBitmap = NULL; | |
| 2093 m_pFile = NULL; | |
| 2094 return m_status = FXCODEC_STATUS_ERROR; | |
| 2095 } | |
| 2096 if (pPause && pPause->NeedToPauseNow()) { | |
| 2097 return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 2098 } | |
| 2099 } | |
| 2100 } break; | |
| 2101 case FXCODEC_IMAGE_GIF: { | |
| 2102 ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); | |
| 2103 while (TRUE) { | |
| 2104 int32_t readRes = | |
| 2105 pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr); | |
| 2106 while (readRes == 2) { | |
| 2107 FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; | |
| 2108 if (!GifReadMoreData(pGifModule, error_status)) { | |
| 2109 m_pDeviceBitmap = NULL; | |
| 2110 m_pFile = NULL; | |
| 2111 return m_status = error_status; | |
| 2112 } | |
| 2113 if (pPause && pPause->NeedToPauseNow()) { | |
| 2114 return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 2115 } | |
| 2116 readRes = pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr); | |
| 2117 } | |
| 2118 if (readRes == 1) { | |
| 2119 m_pDeviceBitmap = NULL; | |
| 2120 m_pFile = NULL; | |
| 2121 return m_status = FXCODEC_STATUS_DECODE_FINISH; | |
| 2122 } | |
| 2123 m_pDeviceBitmap = NULL; | |
| 2124 m_pFile = NULL; | |
| 2125 return m_status = FXCODEC_STATUS_ERROR; | |
| 2126 } | |
| 2127 } break; | |
| 2128 case FXCODEC_IMAGE_BMP: { | |
| 2129 ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); | |
| 2130 while (TRUE) { | |
| 2131 int32_t readRes = pBmpModule->LoadImage(m_pBmpContext); | |
| 2132 while (readRes == 2) { | |
| 2133 FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; | |
| 2134 if (!BmpReadMoreData(pBmpModule, error_status)) { | |
| 2135 m_pDeviceBitmap = NULL; | |
| 2136 m_pFile = NULL; | |
| 2137 return m_status = error_status; | |
| 2138 } | |
| 2139 if (pPause && pPause->NeedToPauseNow()) { | |
| 2140 return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; | |
| 2141 } | |
| 2142 readRes = pBmpModule->LoadImage(m_pBmpContext); | |
| 2143 } | |
| 2144 if (readRes == 1) { | |
| 2145 m_pDeviceBitmap = NULL; | |
| 2146 m_pFile = NULL; | |
| 2147 return m_status = FXCODEC_STATUS_DECODE_FINISH; | |
| 2148 } | |
| 2149 m_pDeviceBitmap = NULL; | |
| 2150 m_pFile = NULL; | |
| 2151 return m_status = FXCODEC_STATUS_ERROR; | |
| 2152 } | |
| 2153 } break; | |
| 2154 case FXCODEC_IMAGE_TIF: { | |
| 2155 ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); | |
| 2156 FX_BOOL ret = FALSE; | |
| 2157 if (m_pDeviceBitmap->GetBPP() == 32 && | |
| 2158 m_pDeviceBitmap->GetWidth() == m_SrcWidth && m_SrcWidth == m_sizeX && | |
| 2159 m_pDeviceBitmap->GetHeight() == m_SrcHeight && | |
| 2160 m_SrcHeight == m_sizeY && m_startX == 0 && m_startY == 0 && | |
| 2161 m_clipBox.left == 0 && m_clipBox.top == 0 && | |
| 2162 m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight) { | |
| 2163 ret = pTiffModule->Decode(m_pTiffContext, m_pDeviceBitmap); | |
| 2164 m_pDeviceBitmap = NULL; | |
| 2165 m_pFile = NULL; | |
| 2166 if (!ret) { | |
| 2167 return m_status = FXCODEC_STATUS_ERROR; | |
| 2168 } | |
| 2169 return m_status = FXCODEC_STATUS_DECODE_FINISH; | |
| 2170 } else { | |
| 2171 CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; | |
| 2172 pDIBitmap->Create(m_SrcWidth, m_SrcHeight, FXDIB_Argb); | |
| 2173 if (pDIBitmap->GetBuffer() == NULL) { | |
| 2174 delete pDIBitmap; | |
| 2175 m_pDeviceBitmap = NULL; | |
| 2176 m_pFile = NULL; | |
| 2177 return m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 2178 } | |
| 2179 ret = pTiffModule->Decode(m_pTiffContext, pDIBitmap); | |
| 2180 if (!ret) { | |
| 2181 delete pDIBitmap; | |
| 2182 m_pDeviceBitmap = NULL; | |
| 2183 m_pFile = NULL; | |
| 2184 return m_status = FXCODEC_STATUS_ERROR; | |
| 2185 } | |
| 2186 CFX_DIBitmap* pClipBitmap = | |
| 2187 (m_clipBox.left == 0 && m_clipBox.top == 0 && | |
| 2188 m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight) | |
| 2189 ? pDIBitmap | |
| 2190 : pDIBitmap->Clone(&m_clipBox); | |
| 2191 if (pDIBitmap != pClipBitmap) { | |
| 2192 delete pDIBitmap; | |
| 2193 } | |
| 2194 if (pClipBitmap == NULL) { | |
| 2195 m_pDeviceBitmap = NULL; | |
| 2196 m_pFile = NULL; | |
| 2197 return m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 2198 } | |
| 2199 CFX_DIBitmap* pFormatBitmap = NULL; | |
| 2200 switch (m_pDeviceBitmap->GetFormat()) { | |
| 2201 case FXDIB_8bppRgb: | |
| 2202 pFormatBitmap = new CFX_DIBitmap; | |
| 2203 pFormatBitmap->Create(pClipBitmap->GetWidth(), | |
| 2204 pClipBitmap->GetHeight(), FXDIB_8bppRgb); | |
| 2205 break; | |
| 2206 case FXDIB_8bppMask: | |
| 2207 pFormatBitmap = new CFX_DIBitmap; | |
| 2208 pFormatBitmap->Create(pClipBitmap->GetWidth(), | |
| 2209 pClipBitmap->GetHeight(), FXDIB_8bppMask); | |
| 2210 break; | |
| 2211 case FXDIB_Rgb: | |
| 2212 pFormatBitmap = new CFX_DIBitmap; | |
| 2213 pFormatBitmap->Create(pClipBitmap->GetWidth(), | |
| 2214 pClipBitmap->GetHeight(), FXDIB_Rgb); | |
| 2215 break; | |
| 2216 case FXDIB_Rgb32: | |
| 2217 pFormatBitmap = new CFX_DIBitmap; | |
| 2218 pFormatBitmap->Create(pClipBitmap->GetWidth(), | |
| 2219 pClipBitmap->GetHeight(), FXDIB_Rgb32); | |
| 2220 break; | |
| 2221 case FXDIB_Argb: | |
| 2222 pFormatBitmap = pClipBitmap; | |
| 2223 break; | |
| 2224 default: | |
| 2225 break; | |
| 2226 } | |
| 2227 switch (m_pDeviceBitmap->GetFormat()) { | |
| 2228 case FXDIB_8bppRgb: | |
| 2229 case FXDIB_8bppMask: { | |
| 2230 for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) { | |
| 2231 uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row); | |
| 2232 uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row); | |
| 2233 for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) { | |
| 2234 uint8_t _a = 255 - src_line[3]; | |
| 2235 uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255; | |
| 2236 uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255; | |
| 2237 uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255; | |
| 2238 *des_line++ = FXRGB2GRAY(r, g, b); | |
| 2239 src_line += 4; | |
| 2240 } | |
| 2241 } | |
| 2242 } break; | |
| 2243 case FXDIB_Rgb: | |
| 2244 case FXDIB_Rgb32: { | |
| 2245 int32_t desBpp = | |
| 2246 (m_pDeviceBitmap->GetFormat() == FXDIB_Rgb) ? 3 : 4; | |
| 2247 for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) { | |
| 2248 uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row); | |
| 2249 uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row); | |
| 2250 for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) { | |
| 2251 uint8_t _a = 255 - src_line[3]; | |
| 2252 uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255; | |
| 2253 uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255; | |
| 2254 uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255; | |
| 2255 *des_line++ = b; | |
| 2256 *des_line++ = g; | |
| 2257 *des_line++ = r; | |
| 2258 des_line += desBpp - 3; | |
| 2259 src_line += 4; | |
| 2260 } | |
| 2261 } | |
| 2262 } break; | |
| 2263 default: | |
| 2264 break; | |
| 2265 } | |
| 2266 if (pClipBitmap != pFormatBitmap) { | |
| 2267 delete pClipBitmap; | |
| 2268 } | |
| 2269 if (pFormatBitmap == NULL) { | |
| 2270 m_pDeviceBitmap = NULL; | |
| 2271 m_pFile = NULL; | |
| 2272 return m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 2273 } | |
| 2274 CFX_DIBitmap* pStrechBitmap = pFormatBitmap->StretchTo( | |
| 2275 m_sizeX, m_sizeY, m_bInterpol ? FXDIB_INTERPOL : FXDIB_DOWNSAMPLE); | |
| 2276 delete pFormatBitmap; | |
| 2277 pFormatBitmap = NULL; | |
| 2278 if (pStrechBitmap == NULL) { | |
| 2279 m_pDeviceBitmap = NULL; | |
| 2280 m_pFile = NULL; | |
| 2281 return m_status = FXCODEC_STATUS_ERR_MEMORY; | |
| 2282 } | |
| 2283 m_pDeviceBitmap->TransferBitmap(m_startX, m_startY, m_sizeX, m_sizeY, | |
| 2284 pStrechBitmap, 0, 0); | |
| 2285 delete pStrechBitmap; | |
| 2286 pStrechBitmap = NULL; | |
| 2287 m_pDeviceBitmap = NULL; | |
| 2288 m_pFile = NULL; | |
| 2289 return m_status = FXCODEC_STATUS_DECODE_FINISH; | |
| 2290 } | |
| 2291 } break; | |
| 2292 default: | |
| 2293 break; | |
| 2294 } | |
| 2295 return FXCODEC_STATUS_ERROR; | |
| 2296 } | |
| 2297 ICodec_ProgressiveDecoder* CCodec_ModuleMgr::CreateProgressiveDecoder() { | |
| 2298 return new CCodec_ProgressiveDecoder(this); | |
| 2299 } | |
| OLD | NEW |