Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
jpx_decode_utils.cpp
Go to the documentation of this file.
1// Copyright 2019 The PDFium Authors
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/fxcodec/jpx/jpx_decode_utils.h"
8
9#include <algorithm>
10#include <limits>
11#include <type_traits>
12
13#include "core/fxcrt/compiler_specific.h"
14#include "core/fxcrt/fx_memcpy_wrappers.h"
15#include "core/fxcrt/numerics/safe_conversions.h"
16
17namespace fxcodec {
18
19DecodeData::DecodeData(pdfium::span<const uint8_t> data)
20 : src_data(data.data()),
21 src_size(pdfium::checked_cast<OPJ_SIZE_T>(data.size())) {}
22
23OPJ_SIZE_T opj_read_from_memory(void* p_buffer,
24 OPJ_SIZE_T nb_bytes,
25 void* p_user_data) {
26 DecodeData* srcData = static_cast<DecodeData*>(p_user_data);
27 if (!srcData || !srcData->src_data || srcData->src_size == 0)
28 return static_cast<OPJ_SIZE_T>(-1);
29
30 // Reads at EOF return an error code.
31 if (srcData->offset >= srcData->src_size)
32 return static_cast<OPJ_SIZE_T>(-1);
33
35 OPJ_SIZE_T bufferLength = srcData->src_size - srcData->offset;
36 OPJ_SIZE_T readlength = nb_bytes < bufferLength ? nb_bytes : bufferLength;
37 FXSYS_memcpy(p_buffer, &srcData->src_data[srcData->offset], readlength);
38 srcData->offset += readlength;
39 return readlength;
40 })
41}
42
43OPJ_OFF_T opj_skip_from_memory(OPJ_OFF_T nb_bytes, void* p_user_data) {
44 DecodeData* srcData = static_cast<DecodeData*>(p_user_data);
45 if (!srcData || !srcData->src_data || srcData->src_size == 0)
46 return static_cast<OPJ_OFF_T>(-1);
47
48 // Offsets are signed and may indicate a negative skip. Do not support this
49 // because of the strange return convention where either bytes skipped or
50 // -1 is returned. Following that convention, a successful relative seek of
51 // -1 bytes would be required to to give the same result as the error case.
52 if (nb_bytes < 0)
53 return static_cast<OPJ_OFF_T>(-1);
54
55 auto unsigned_nb_bytes =
56 static_cast<std::make_unsigned<OPJ_OFF_T>::type>(nb_bytes);
57 // Additionally, the offset may take us beyond the range of a size_t (e.g.
58 // 32-bit platforms). If so, just clamp at EOF.
59 if (unsigned_nb_bytes >
60 std::numeric_limits<OPJ_SIZE_T>::max() - srcData->offset) {
61 srcData->offset = srcData->src_size;
62 } else {
63 OPJ_SIZE_T checked_nb_bytes = static_cast<OPJ_SIZE_T>(unsigned_nb_bytes);
64 // Otherwise, mimic fseek() semantics to always succeed, even past EOF,
65 // clamping at EOF. We can get away with this since we don't actually
66 // provide negative relative skips from beyond EOF back to inside the
67 // data, which would be the only reason to need to know exactly how far
68 // beyond EOF we are.
69 srcData->offset =
70 std::min(srcData->offset + checked_nb_bytes, srcData->src_size);
71 }
72 return nb_bytes;
73}
74
75OPJ_BOOL opj_seek_from_memory(OPJ_OFF_T nb_bytes, void* p_user_data) {
76 DecodeData* srcData = static_cast<DecodeData*>(p_user_data);
77 if (!srcData || !srcData->src_data || srcData->src_size == 0)
78 return OPJ_FALSE;
79
80 // Offsets are signed and may indicate a negative position, which would
81 // be before the start of the file. Do not support this.
82 if (nb_bytes < 0)
83 return OPJ_FALSE;
84
85 auto unsigned_nb_bytes =
86 static_cast<std::make_unsigned<OPJ_OFF_T>::type>(nb_bytes);
87 // Additionally, the offset may take us beyond the range of a size_t (e.g.
88 // 32-bit platforms). If so, just clamp at EOF.
89 if (unsigned_nb_bytes > std::numeric_limits<OPJ_SIZE_T>::max()) {
90 srcData->offset = srcData->src_size;
91 } else {
92 OPJ_SIZE_T checked_nb_bytes = static_cast<OPJ_SIZE_T>(nb_bytes);
93 // Otherwise, mimic fseek() semantics to always succeed, even past EOF,
94 // again clamping at EOF.
95 srcData->offset = std::min(checked_nb_bytes, srcData->src_size);
96 }
97 return OPJ_TRUE;
98}
99
100} // namespace fxcodec
#define UNSAFE_TODO(...)
UNSAFE_BUFFER_USAGE void * FXSYS_memcpy(void *ptr1, const void *ptr2, size_t len)
OPJ_BOOL opj_seek_from_memory(OPJ_OFF_T nb_bytes, void *p_user_data)
OPJ_SIZE_T opj_read_from_memory(void *p_buffer, OPJ_SIZE_T nb_bytes, void *p_user_data)
OPJ_OFF_T opj_skip_from_memory(OPJ_OFF_T nb_bytes, void *p_user_data)
DecodeData(pdfium::span< const uint8_t > data)
const uint8_t * src_data