1
0

DLTADecode.cpp 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /* Copyright (C) Teemu Suutari */
  2. #include "DLTADecode.hpp"
  3. #include "common/OverflowCheck.hpp"
  4. #include "common/Common.hpp"
  5. namespace ancient::internal
  6. {
  7. bool DLTADecode::detectHeaderXPK(uint32_t hdr) noexcept
  8. {
  9. return hdr==FourCC("DLTA");
  10. }
  11. std::shared_ptr<XPKDecompressor> DLTADecode::create(uint32_t hdr,uint32_t recursionLevel,const Buffer &packedData,std::shared_ptr<XPKDecompressor::State> &state,bool verify)
  12. {
  13. return std::make_shared<DLTADecode>(hdr,recursionLevel,packedData,state,verify);
  14. }
  15. DLTADecode::DLTADecode(uint32_t hdr,uint32_t recursionLevel,const Buffer &packedData,std::shared_ptr<XPKDecompressor::State> &state,bool verify) :
  16. XPKDecompressor(recursionLevel),
  17. _packedData(packedData)
  18. {
  19. if (!detectHeaderXPK(hdr)) throw Decompressor::InvalidFormatError();
  20. }
  21. DLTADecode::~DLTADecode()
  22. {
  23. // nothing needed
  24. }
  25. const std::string &DLTADecode::getSubName() const noexcept
  26. {
  27. static std::string name="XPK-DLTA: Delta encoding";
  28. return name;
  29. }
  30. void DLTADecode::decode(Buffer &bufferDest,const Buffer &bufferSrc,size_t offset,size_t size)
  31. {
  32. if (OverflowCheck::sum(offset,size)>bufferSrc.size()) throw Buffer::OutOfBoundsError();
  33. if (OverflowCheck::sum(offset,size)>bufferDest.size()) throw Buffer::OutOfBoundsError();
  34. const uint8_t *src=bufferSrc.data()+offset;
  35. uint8_t *dest=bufferDest.data()+offset;
  36. uint8_t ctr=0;
  37. for (size_t i=0;i<size;i++)
  38. {
  39. ctr+=src[i];
  40. dest[i]=ctr;
  41. }
  42. }
  43. void DLTADecode::decompressImpl(Buffer &rawData,const Buffer &previousData,bool verify)
  44. {
  45. if (rawData.size()<_packedData.size()) throw Decompressor::DecompressionError();
  46. decode(rawData,_packedData,0,_packedData.size());
  47. }
  48. }