Skip to content

Commit b7ca919

Browse files
committed
Support decoding on big endian systems
1 parent 09decd2 commit b7ca919

File tree

8 files changed

+737
-665
lines changed

8 files changed

+737
-665
lines changed

build.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from pathlib import Path
44
import platform
55
import shutil
6+
from struct import unpack
67
import subprocess
78
import sys
89
from typing import Any, List, Dict
@@ -33,9 +34,17 @@ def build(setup_kwargs: Any) -> Any:
3334
# Skip configuration if running with `sdist`
3435
if 'sdist' not in sys.argv:
3536
opts = get_gcc_args()
37+
if sys.byteorder == "big":
38+
if "-mfpmath=387" in opts["ADDOPTS"]:
39+
opts["ADDOPTS"].remove("-mfpmath=387")
40+
3641
extra_compile_args += opts['ADDOPTS']
3742
extra_link_args += opts['EXTRA_LIBS']
3843

44+
macros = [("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")]
45+
if unpack("h", b"\x00\x01")[0] == 1:
46+
macros.append(("JPG_BIG_ENDIAN", "1"))
47+
3948
ext = Extension(
4049
'_libjpeg',
4150
[os.fspath(p) for p in get_source_files()],
@@ -47,6 +56,7 @@ def build(setup_kwargs: Any) -> Any:
4756
],
4857
extra_compile_args=extra_compile_args,
4958
extra_link_args=extra_link_args,
59+
define_macros=macros,
5060
)
5161

5262
ext_modules = cythonize(

docs/changes/v2.1.0.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.. _v2.1.0:
2+
3+
2.1.0
4+
=====
5+
6+
* Use ``libjpeg`` v1.67
7+
* Fixed a decoding failure for JPEG 10918 file with an Adobe v101 APP14 marker
8+
9+
2.1.1
10+
=====
11+
12+
* Updated dependencies to allow NumPy > 2.0
13+
* Tests updated to use ``pydicom.pixels``

docs/changes/v2.2.0.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.. _v2.2.0:
2+
3+
2.2.0
4+
=====
5+
6+
* Support NumPy > 2.0 with Python 3.9+

docs/changes/v2.3.0.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.. _v2.3.0:
2+
3+
2.3.0
4+
=====
5+
6+
* Supported Python versions are 3.9 to 3.13
7+
* Added support for decoding on big endian systems

lib/interface/decode.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ std::string Decode(
3030
Parameters
3131
----------
3232
char *inArray
33-
Pointer to the first element of a numpy.ndarray containing the JPEG
34-
data to be decompressed.
33+
Pointer to the first element of a bytearray or numpy.ndarray containing the
34+
JPEG data to be decompressed.
3535
char *outArray
36-
Pointer to the first element of a numpy.ndarray where the decompressed
37-
JPEG data should be written.
36+
Pointer to the first element of bytearray or numpy.ndarray where the
37+
decompressed JPEG data should be written.
3838
int inLength
3939
Length of the input array
4040
int outLength

lib/interface/streamhook.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ JPG_LONG OStreamHook(struct JPG_Hook *hook, struct JPG_TagItem *tags)
8888
static ULONG OpenComponents = 0;
8989
struct StreamMemory *omm = (struct StreamMemory *)(hook->hk_pData);
9090
struct StreamData *out = (struct StreamData *)(omm->omm_pTarget);
91-
// Pointer to the output numpy array, currently at offset out->position
91+
// Pointer to the output bytearray/numpy array, currently at offset out->position
9292
char *oArray = (char *)(out->pData);
9393

9494
UWORD comp = tags->GetTagData(JPGTAG_BIO_COMPONENT);
@@ -323,12 +323,26 @@ JPG_LONG OStreamHook(struct JPG_Hook *hook, struct JPG_TagItem *tags)
323323
}
324324
} else {
325325
// DICOM should always be integer input
326-
// Write pixel data to target
326+
// Need to byte swap if on a big endian system
327+
#ifdef JPG_BIG_ENDIAN
328+
ULONG count = width * height * omm->omm_usDepth;
329+
if (omm->omm_ucPixelType == CTYP_UWORD) {
330+
// ULONG count = width * height * omm->omm_usDepth;
331+
UWORD *data = (UWORD *)omm->omm_pMemPtr;
332+
333+
do {
334+
*data = (*data >> 8) | ((*data & 0xff) << 8);
335+
data++;
336+
} while(--count);
337+
}
338+
#endif
339+
340+
// Write the decoded data to the output
341+
// For each pixel
342+
ULONG count2 = width * height * omm->omm_usDepth;
327343
ULONG size = omm->omm_ucPixelType & CTYP_SIZE_MASK;
328-
ULONG count = width * height * omm->omm_usDepth;
329344
UBYTE *mem = (UBYTE *)(omm->omm_pMemPtr);
330-
// For each pixel
331-
for (ULONG ii = 1; ii <= count; ii++) {
345+
for (ULONG ii = 1; ii <= count2; ii++) {
332346
// For each byte of the pixel
333347
for (ULONG jj = 1; jj <= size; jj++) {
334348
if (out->position >= out->length) {

0 commit comments

Comments
 (0)