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 |