| 586 | #endif |
| 587 | |
| 588 | void Jp2Image::encodeJp2Header(const DataBuf& boxBuf, DataBuf& outBuf) { |
| 589 | DataBuf output(boxBuf.size() + iccProfile_.size() + 100); // allocate sufficient space |
| 590 | size_t outlen = boxHSize; // now many bytes have we written to output? |
| 591 | size_t inlen = boxHSize; // how many bytes have we read from boxBuf? |
| 592 | Internal::enforce(boxHSize <= output.size(), ErrorCode::kerCorruptedMetadata); |
| 593 | uint32_t length = getULong(boxBuf.c_data(0), bigEndian); |
| 594 | Internal::enforce(length <= output.size(), ErrorCode::kerCorruptedMetadata); |
| 595 | uint32_t count = boxHSize; |
| 596 | bool bWroteColor = false; |
| 597 | |
| 598 | while (count < length && !bWroteColor) { |
| 599 | Internal::enforce(boxHSize <= length - count, ErrorCode::kerCorruptedMetadata); |
| 600 | Internal::Jp2BoxHeader subBox; |
| 601 | memcpy(&subBox, boxBuf.c_data(count), boxHSize); |
| 602 | Internal::Jp2BoxHeader newBox = subBox; |
| 603 | |
| 604 | if (count < length) { |
| 605 | subBox.length = getULong(boxBuf.c_data(count), bigEndian); |
| 606 | subBox.type = getULong(boxBuf.c_data(count + 4), bigEndian); |
| 607 | #ifdef EXIV2_DEBUG_MESSAGES |
| 608 | std::cout << "Jp2Image::encodeJp2Header subbox: " << toAscii(subBox.type) << " length = " << subBox.length |
| 609 | << std::endl; |
| 610 | #endif |
| 611 | Internal::enforce(subBox.length > 0, ErrorCode::kerCorruptedMetadata); |
| 612 | Internal::enforce(subBox.length <= length - count, ErrorCode::kerCorruptedMetadata); |
| 613 | count += subBox.length; |
| 614 | newBox.type = subBox.type; |
| 615 | } else { |
| 616 | subBox.length = 0; |
| 617 | newBox.type = kJp2BoxTypeColorSpec; |
| 618 | count = length; |
| 619 | } |
| 620 | |
| 621 | size_t newlen = subBox.length; |
| 622 | if (newBox.type == kJp2BoxTypeColorSpec) { |
| 623 | bWroteColor = true; |
| 624 | if (!iccProfileDefined()) { |
| 625 | const char* pad = "\x01\x00\x00\x00\x00\x00\x10\x00\x00\x05\x1cuuid"; |
| 626 | uint32_t psize = 15; |
| 627 | Internal::enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata); |
| 628 | ul2Data(reinterpret_cast<byte*>(&newBox.length), psize, bigEndian); |
| 629 | ul2Data(reinterpret_cast<byte*>(&newBox.type), newBox.type, bigEndian); |
| 630 | std::copy_n(reinterpret_cast<char*>(&newBox), sizeof(newBox), output.begin() + outlen); |
| 631 | std::copy_n(pad, psize, output.begin() + outlen + sizeof(newBox)); |
| 632 | } else { |
| 633 | const char* pad = "\x02\x00\x00"; |
| 634 | uint32_t psize = 3; |
| 635 | newlen = sizeof(newBox) + psize + iccProfile_.size(); |
| 636 | Internal::enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata); |
| 637 | ul2Data(reinterpret_cast<byte*>(&newBox.length), static_cast<uint32_t>(newlen), bigEndian); |
| 638 | ul2Data(reinterpret_cast<byte*>(&newBox.type), newBox.type, bigEndian); |
| 639 | std::copy_n(reinterpret_cast<char*>(&newBox), sizeof(newBox), output.begin() + outlen); |
| 640 | std::copy_n(pad, psize, output.begin() + outlen + sizeof(newBox)); |
| 641 | std::copy(iccProfile_.begin(), iccProfile_.end(), output.begin() + outlen + sizeof(newBox) + psize); |
| 642 | } |
| 643 | } else { |
| 644 | Internal::enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata); |
| 645 | std::copy_n(boxBuf.c_data(inlen), subBox.length, output.begin() + outlen); |