| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "../../../include/fxcodec/fx_codec.h" | 7 #include "../../../include/fxcodec/fx_codec.h" |
| 8 | 8 |
| 9 #include <cmath> | 9 #include <cmath> |
| 10 | 10 |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 } | 250 } |
| 251 } | 251 } |
| 252 return is_negative ? -ret : ret; | 252 return is_negative ? -ret : ret; |
| 253 } | 253 } |
| 254 FX_BOOL CCodec_BasicModule::A85Encode(const uint8_t* src_buf, | 254 FX_BOOL CCodec_BasicModule::A85Encode(const uint8_t* src_buf, |
| 255 FX_DWORD src_size, | 255 FX_DWORD src_size, |
| 256 uint8_t*& dest_buf, | 256 uint8_t*& dest_buf, |
| 257 FX_DWORD& dest_size) { | 257 FX_DWORD& dest_size) { |
| 258 return FALSE; | 258 return FALSE; |
| 259 } | 259 } |
| 260 CFX_DIBAttribute::CFX_DIBAttribute() { | 260 CFX_DIBAttribute::CFX_DIBAttribute() |
| 261 FXSYS_memset(this, 0, sizeof(CFX_DIBAttribute)); | 261 : m_nXDPI(-1), |
| 262 m_nXDPI = -1; | 262 m_nYDPI(-1), |
| 263 m_nYDPI = -1; | 263 m_fAspectRatio(-1.0f), |
| 264 m_fAspectRatio = -1.0f; | 264 m_wDPIUnit(0), |
| 265 m_pExif = new CFX_DIBAttributeExif; | 265 m_nGifLeft(0), |
| 266 m_nGifTop(0), |
| 267 m_pGifLocalPalette(nullptr), |
| 268 m_nGifLocalPalNum(0), |
| 269 m_nBmpCompressType(0) { |
| 270 FXSYS_memset(m_strTime, 0, sizeof(m_strTime)); |
| 266 } | 271 } |
| 267 CFX_DIBAttribute::~CFX_DIBAttribute() { | 272 CFX_DIBAttribute::~CFX_DIBAttribute() { |
| 268 if (m_pExif) { | 273 for (const auto& pair : m_Exif) |
| 269 delete m_pExif; | 274 FX_Free(pair.second); |
| 270 } | |
| 271 } | 275 } |
| 272 CFX_DIBAttributeExif::CFX_DIBAttributeExif() { | 276 |
| 273 m_pExifData = NULL; | |
| 274 m_dwExifDataLen = 0; | |
| 275 } | |
| 276 CFX_DIBAttributeExif::~CFX_DIBAttributeExif() { | |
| 277 clear(); | |
| 278 } | |
| 279 void CFX_DIBAttributeExif::clear() { | |
| 280 if (m_pExifData) { | |
| 281 FX_Free(m_pExifData); | |
| 282 } | |
| 283 m_pExifData = NULL; | |
| 284 FX_DWORD key = 0; | |
| 285 uint8_t* buf = NULL; | |
| 286 FX_POSITION pos = NULL; | |
| 287 pos = m_TagHead.GetStartPosition(); | |
| 288 while (pos) { | |
| 289 m_TagHead.GetNextAssoc(pos, key, buf); | |
| 290 if (buf) { | |
| 291 FX_Free(buf); | |
| 292 } | |
| 293 } | |
| 294 m_TagHead.RemoveAll(); | |
| 295 pos = m_TagVal.GetStartPosition(); | |
| 296 while (pos) { | |
| 297 m_TagVal.GetNextAssoc(pos, key, buf); | |
| 298 if (buf) { | |
| 299 FX_Free(buf); | |
| 300 } | |
| 301 } | |
| 302 m_TagVal.RemoveAll(); | |
| 303 } | |
| 304 static FX_WORD _Read2BytesL(uint8_t* data) { | |
| 305 ASSERT(data); | |
| 306 return data[0] | (data[1] << 8); | |
| 307 } | |
| 308 static FX_WORD _Read2BytesB(uint8_t* data) { | |
| 309 ASSERT(data); | |
| 310 return data[1] | (data[0] << 8); | |
| 311 } | |
| 312 static FX_DWORD _Read4BytesL(uint8_t* data) { | |
| 313 return _Read2BytesL(data) | (_Read2BytesL(data + 2) << 16); | |
| 314 } | |
| 315 static FX_DWORD _Read4BytesB(uint8_t* data) { | |
| 316 return _Read2BytesB(data + 2) | (_Read2BytesB(data) << 16); | |
| 317 } | |
| 318 typedef FX_WORD (*_Read2Bytes)(uint8_t* data); | |
| 319 typedef FX_DWORD (*_Read4Bytes)(uint8_t* data); | |
| 320 typedef void (*_Write2Bytes)(uint8_t* data, FX_WORD val); | |
| 321 typedef void (*_Write4Bytes)(uint8_t* data, FX_DWORD val); | |
| 322 uint8_t* CFX_DIBAttributeExif::ParseExifIFH(uint8_t* data, | |
| 323 FX_DWORD len, | |
| 324 _Read2Bytes* pReadWord, | |
| 325 _Read4Bytes* pReadDword) { | |
| 326 if (len > 8) { | |
| 327 FX_BOOL tag = FALSE; | |
| 328 if (FXSYS_memcmp(data, "\x49\x49\x2a\x00", 4) == 0) { | |
| 329 if (pReadWord) { | |
| 330 *pReadWord = _Read2BytesL; | |
| 331 } | |
| 332 if (pReadDword) { | |
| 333 *pReadDword = _Read4BytesL; | |
| 334 } | |
| 335 tag = TRUE; | |
| 336 } else if (FXSYS_memcmp(data, "\x4d\x4d\x00\x2a", 4) == 0) { | |
| 337 if (pReadWord) { | |
| 338 *pReadWord = _Read2BytesB; | |
| 339 } | |
| 340 if (pReadDword) { | |
| 341 *pReadDword = _Read4BytesB; | |
| 342 } | |
| 343 tag = TRUE; | |
| 344 } | |
| 345 if (tag) { | |
| 346 data += 4; | |
| 347 if (pReadDword) { | |
| 348 data += (*pReadDword)(data)-4; | |
| 349 } else { | |
| 350 data += 4; | |
| 351 } | |
| 352 } | |
| 353 } | |
| 354 return data; | |
| 355 } | |
| 356 FX_BOOL CFX_DIBAttributeExif::ParseExifIFD( | |
| 357 CFX_MapPtrTemplate<FX_DWORD, uint8_t*>* pMap, | |
| 358 uint8_t* data, | |
| 359 FX_DWORD len) { | |
| 360 if (pMap && data) { | |
| 361 if (len > 8) { | |
| 362 FX_WORD wTagNum = m_readWord(data); | |
| 363 data += 2; | |
| 364 FX_DWORD wTag; | |
| 365 uint8_t* buf; | |
| 366 while (wTagNum--) { | |
| 367 wTag = m_readWord(data); | |
| 368 data += 2; | |
| 369 if (!pMap->Lookup(wTag, buf)) { | |
| 370 buf = FX_Alloc(uint8_t, 10); | |
| 371 if (buf == NULL) { | |
| 372 return FALSE; | |
| 373 } | |
| 374 FXSYS_memcpy(buf, data, 10); | |
| 375 pMap->SetAt(wTag, buf); | |
| 376 } | |
| 377 data += 10; | |
| 378 } | |
| 379 FX_DWORD dwIFDOffset; | |
| 380 dwIFDOffset = m_readDword(data); | |
| 381 while (dwIFDOffset && dwIFDOffset < len) { | |
| 382 data = m_pExifData + dwIFDOffset; | |
| 383 wTagNum = m_readWord(data); | |
| 384 data += 2; | |
| 385 while (wTagNum--) { | |
| 386 wTag = m_readWord(data); | |
| 387 data += 2; | |
| 388 if (!pMap->Lookup(wTag, buf)) { | |
| 389 buf = FX_Alloc(uint8_t, 10); | |
| 390 if (buf == NULL) { | |
| 391 return FALSE; | |
| 392 } | |
| 393 FXSYS_memcpy(buf, data, 10); | |
| 394 pMap->SetAt(wTag, buf); | |
| 395 } | |
| 396 data += 10; | |
| 397 } | |
| 398 dwIFDOffset = m_readDword(data); | |
| 399 } | |
| 400 return TRUE; | |
| 401 } | |
| 402 } | |
| 403 return FALSE; | |
| 404 } | |
| 405 enum FX_ExifDataType { | |
| 406 FX_UnsignedByte = 1, | |
| 407 FX_AscString, | |
| 408 FX_UnsignedShort, | |
| 409 FX_UnsignedLong, | |
| 410 FX_UnsignedRation, | |
| 411 FX_SignedByte, | |
| 412 FX_Undefined, | |
| 413 FX_SignedShort, | |
| 414 FX_SignedLong, | |
| 415 FX_SignedRation, | |
| 416 FX_SignedFloat, | |
| 417 FX_DoubleFloat | |
| 418 }; | |
| 419 FX_BOOL CFX_DIBAttributeExif::ParseExif( | |
| 420 CFX_MapPtrTemplate<FX_DWORD, uint8_t*>* pHead, | |
| 421 uint8_t* data, | |
| 422 FX_DWORD len, | |
| 423 CFX_MapPtrTemplate<FX_DWORD, uint8_t*>* pVal) { | |
| 424 if (pHead && data && pVal) { | |
| 425 if (len > 8) { | |
| 426 uint8_t* old_data = data; | |
| 427 data = ParseExifIFH(data, len, &m_readWord, &m_readDword); | |
| 428 if (data == old_data) { | |
| 429 return FALSE; | |
| 430 } | |
| 431 if (pHead->GetCount() == 0) { | |
| 432 if (!ParseExifIFD(pHead, data, len)) { | |
| 433 return FALSE; | |
| 434 } | |
| 435 } | |
| 436 FX_DWORD dwModuleNum; | |
| 437 FX_WORD type; | |
| 438 FX_DWORD dwSize; | |
| 439 FX_DWORD tag; | |
| 440 uint8_t* head; | |
| 441 FX_POSITION pos = pHead->GetStartPosition(); | |
| 442 while (pos) { | |
| 443 pHead->GetNextAssoc(pos, tag, head); | |
| 444 uint8_t* val = NULL; | |
| 445 uint8_t* buf = NULL; | |
| 446 uint8_t* temp = NULL; | |
| 447 int i; | |
| 448 if (head) { | |
| 449 type = m_readWord(head); | |
| 450 head += 2; | |
| 451 dwModuleNum = m_readDword(head); | |
| 452 head += 4; | |
| 453 switch (type) { | |
| 454 case FX_UnsignedByte: | |
| 455 case FX_AscString: | |
| 456 case FX_SignedByte: | |
| 457 case FX_Undefined: | |
| 458 dwSize = dwModuleNum; | |
| 459 val = FX_Alloc(uint8_t, dwSize); | |
| 460 if (val == NULL) { | |
| 461 return FALSE; | |
| 462 } | |
| 463 if (dwSize > 4) { | |
| 464 FXSYS_memcpy(val, old_data + m_readDword(head), dwSize); | |
| 465 } else { | |
| 466 FXSYS_memcpy(val, head, dwSize); | |
| 467 } | |
| 468 break; | |
| 469 case FX_UnsignedShort: | |
| 470 case FX_SignedShort: | |
| 471 dwSize = dwModuleNum << 1; | |
| 472 val = FX_Alloc(uint8_t, dwSize); | |
| 473 if (val == NULL) { | |
| 474 return FALSE; | |
| 475 } | |
| 476 if (dwSize > 4) { | |
| 477 FXSYS_memcpy(val, old_data + m_readDword(head), dwSize); | |
| 478 } else { | |
| 479 FXSYS_memcpy(val, head, dwSize); | |
| 480 } | |
| 481 buf = val; | |
| 482 for (i = 0; i < (int)dwModuleNum; i++) { | |
| 483 *(FX_WORD*)buf = m_readWord(buf); | |
| 484 buf += 2; | |
| 485 } | |
| 486 break; | |
| 487 case FX_UnsignedLong: | |
| 488 case FX_SignedLong: | |
| 489 case FX_SignedFloat: | |
| 490 dwSize = dwModuleNum << 2; | |
| 491 val = FX_Alloc(uint8_t, dwSize); | |
| 492 if (val == NULL) { | |
| 493 return FALSE; | |
| 494 } | |
| 495 if (dwSize > 4) { | |
| 496 FXSYS_memcpy(val, old_data + m_readDword(head), dwSize); | |
| 497 } else { | |
| 498 FXSYS_memcpy(val, head, dwSize); | |
| 499 } | |
| 500 buf = val; | |
| 501 for (i = 0; i < (int)dwModuleNum; i++) { | |
| 502 *(FX_DWORD*)buf = m_readDword(buf); | |
| 503 buf += 4; | |
| 504 } | |
| 505 break; | |
| 506 case FX_UnsignedRation: | |
| 507 case FX_SignedRation: { | |
| 508 dwSize = dwModuleNum << 3; | |
| 509 buf = FX_Alloc(uint8_t, dwSize); | |
| 510 if (buf == NULL) { | |
| 511 return FALSE; | |
| 512 } | |
| 513 if (dwSize > 4) { | |
| 514 FXSYS_memcpy(buf, old_data + m_readDword(head), dwSize); | |
| 515 } else { | |
| 516 FXSYS_memcpy(buf, head, dwSize); | |
| 517 } | |
| 518 temp = buf; | |
| 519 val = FX_Alloc(uint8_t, dwSize / 2); | |
| 520 if (val == NULL) { | |
| 521 FX_Free(buf); | |
| 522 return FALSE; | |
| 523 } | |
| 524 for (i = 0; i < (int)dwModuleNum; i++) { | |
| 525 *(FX_DWORD*)temp = m_readDword(temp); | |
| 526 *(FX_DWORD*)(temp + 4) = m_readDword(temp + 4); | |
| 527 FX_DWORD* lNumerator = (FX_DWORD*)temp; | |
| 528 FX_DWORD* lNenominator = (FX_DWORD*)(temp + 4); | |
| 529 *(FX_FLOAT*)(val + i * 4) = | |
| 530 (FX_FLOAT)(*lNumerator) / (FX_FLOAT)(*lNenominator); | |
| 531 temp += 8; | |
| 532 } | |
| 533 FX_Free(buf); | |
| 534 } break; | |
| 535 case FX_DoubleFloat: | |
| 536 dwSize = dwModuleNum << 3; | |
| 537 val = FX_Alloc(uint8_t, dwSize); | |
| 538 if (val == NULL) { | |
| 539 return FALSE; | |
| 540 } | |
| 541 if (dwSize > 4) { | |
| 542 FXSYS_memcpy(val, old_data + m_readDword(head), dwSize); | |
| 543 } else { | |
| 544 FXSYS_memcpy(val, head, dwSize); | |
| 545 } | |
| 546 buf = val; | |
| 547 for (i = 0; i < (int)dwModuleNum; i++) { | |
| 548 *(FX_DWORD*)buf = m_readDword(buf); | |
| 549 *(FX_DWORD*)(buf + 4) = m_readDword(buf + 4); | |
| 550 buf += 8; | |
| 551 } | |
| 552 break; | |
| 553 default: | |
| 554 return FALSE; | |
| 555 } | |
| 556 } | |
| 557 pVal->SetAt(tag, val); | |
| 558 } | |
| 559 return TRUE; | |
| 560 } | |
| 561 } | |
| 562 return FALSE; | |
| 563 } | |
| 564 #define FXEXIF_INFOCONVERT(T) \ | |
| 565 { \ | |
| 566 T* src = (T*)ptr; \ | |
| 567 T* dst = (T*)val; \ | |
| 568 *dst = *src; \ | |
| 569 } | |
| 570 FX_BOOL CFX_DIBAttributeExif::GetInfo(FX_WORD tag, void* val) { | |
| 571 if (m_TagVal.GetCount() == 0) { | |
| 572 if (!ParseExif(&m_TagHead, m_pExifData, m_dwExifDataLen, &m_TagVal)) { | |
| 573 return FALSE; | |
| 574 } | |
| 575 } | |
| 576 uint8_t* ptr = NULL; | |
| 577 if (m_TagVal.Lookup(tag, ptr)) { | |
| 578 switch (tag) { | |
| 579 case EXIFTAG_USHORT_RESUNIT: | |
| 580 FXEXIF_INFOCONVERT(FX_WORD); | |
| 581 { | |
| 582 FX_WORD* ptr = (FX_WORD*)val; | |
| 583 *ptr -= 1; | |
| 584 } | |
| 585 break; | |
| 586 case EXIFTAG_FLOAT_DPIX: | |
| 587 case EXIFTAG_FLOAT_DPIY: | |
| 588 FXEXIF_INFOCONVERT(FX_FLOAT); | |
| 589 break; | |
| 590 case EXIFTAG_USHORT_ORIENTATION: | |
| 591 FXEXIF_INFOCONVERT(FX_WORD); | |
| 592 break; | |
| 593 default: { | |
| 594 uint8_t** dst = (uint8_t**)val; | |
| 595 *dst = ptr; | |
| 596 } | |
| 597 } | |
| 598 } | |
| 599 return TRUE; | |
| 600 } | |
| 601 class CCodec_RLScanlineDecoder : public CCodec_ScanlineDecoder { | 277 class CCodec_RLScanlineDecoder : public CCodec_ScanlineDecoder { |
| 602 public: | 278 public: |
| 603 CCodec_RLScanlineDecoder(); | 279 CCodec_RLScanlineDecoder(); |
| 604 ~CCodec_RLScanlineDecoder() override; | 280 ~CCodec_RLScanlineDecoder() override; |
| 605 | 281 |
| 606 FX_BOOL Create(const uint8_t* src_buf, | 282 FX_BOOL Create(const uint8_t* src_buf, |
| 607 FX_DWORD src_size, | 283 FX_DWORD src_size, |
| 608 int width, | 284 int width, |
| 609 int height, | 285 int height, |
| 610 int nComps, | 286 int nComps, |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 784 int nComps, | 460 int nComps, |
| 785 int bpc) { | 461 int bpc) { |
| 786 CCodec_RLScanlineDecoder* pRLScanlineDecoder = new CCodec_RLScanlineDecoder; | 462 CCodec_RLScanlineDecoder* pRLScanlineDecoder = new CCodec_RLScanlineDecoder; |
| 787 if (!pRLScanlineDecoder->Create(src_buf, src_size, width, height, nComps, | 463 if (!pRLScanlineDecoder->Create(src_buf, src_size, width, height, nComps, |
| 788 bpc)) { | 464 bpc)) { |
| 789 delete pRLScanlineDecoder; | 465 delete pRLScanlineDecoder; |
| 790 return NULL; | 466 return NULL; |
| 791 } | 467 } |
| 792 return pRLScanlineDecoder; | 468 return pRLScanlineDecoder; |
| 793 } | 469 } |
| OLD | NEW |