Skip to content

Commit 4c704f0

Browse files
committed
Add support for big endian systems
1 parent 765ce80 commit 4c704f0

File tree

6 files changed

+726
-680
lines changed

6 files changed

+726
-680
lines changed

.github/workflows/pytest-builds.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
strategy:
1313
fail-fast: false
1414
matrix:
15-
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
15+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
1616
arch: ['x64', 'x86']
1717

1818
steps:
@@ -48,7 +48,7 @@ jobs:
4848
strategy:
4949
fail-fast: false
5050
matrix:
51-
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
51+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
5252

5353
steps:
5454
- uses: actions/checkout@v4
@@ -82,7 +82,7 @@ jobs:
8282
strategy:
8383
fail-fast: false
8484
matrix:
85-
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
85+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
8686

8787
steps:
8888
- uses: actions/checkout@v4
@@ -106,7 +106,7 @@ jobs:
106106
pytest --cov openjpeg openjpeg/tests
107107
108108
- name: Install pydicom dev and rerun pytest (3.10+)
109-
if: ${{ contains('3.10 3.11 3.12', matrix.python-version) }}
109+
if: ${{ contains('3.10 3.11 3.12 3.13', matrix.python-version) }}
110110
run: |
111111
pip install pylibjpeg
112112
pip install git+https://github.com/pydicom/pydicom

.github/workflows/release-wheels.yml

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ jobs:
4242
matrix:
4343
include:
4444
# Windows 32 bit
45-
- os: windows-latest
46-
python: 38
47-
platform_id: win32
4845
- os: windows-latest
4946
python: 39
5047
platform_id: win32
@@ -57,11 +54,11 @@ jobs:
5754
- os: windows-latest
5855
python: 312
5956
platform_id: win32
57+
- os: windows-latest
58+
python: 313
59+
platform_id: win32
6060

6161
# Windows 64 bit
62-
- os: windows-latest
63-
python: 38
64-
platform_id: win_amd64
6562
- os: windows-latest
6663
python: 39
6764
platform_id: win_amd64
@@ -74,12 +71,11 @@ jobs:
7471
- os: windows-latest
7572
python: 312
7673
platform_id: win_amd64
74+
- os: windows-latest
75+
python: 313
76+
platform_id: win_amd64
7777

7878
# Linux 64 bit manylinux2014
79-
- os: ubuntu-latest
80-
python: 38
81-
platform_id: manylinux_x86_64
82-
manylinux_image: manylinux2014
8379
- os: ubuntu-latest
8480
python: 39
8581
platform_id: manylinux_x86_64
@@ -96,11 +92,12 @@ jobs:
9692
python: 312
9793
platform_id: manylinux_x86_64
9894
manylinux_image: manylinux2014
95+
- os: ubuntu-latest
96+
python: 313
97+
platform_id: manylinux_x86_64
98+
manylinux_image: manylinux2014
9999

100100
# Linux aarch64
101-
- os: ubuntu-latest
102-
python: 38
103-
platform_id: manylinux_aarch64
104101
- os: ubuntu-latest
105102
python: 39
106103
platform_id: manylinux_aarch64
@@ -113,11 +110,11 @@ jobs:
113110
- os: ubuntu-latest
114111
python: 312
115112
platform_id: manylinux_aarch64
113+
- os: ubuntu-latest
114+
python: 313
115+
platform_id: manylinux_aarch64
116116

117117
# MacOS 12 x86_64
118-
- os: macos-12
119-
python: 38
120-
platform_id: macosx_x86_64
121118
- os: macos-12
122119
python: 39
123120
platform_id: macosx_x86_64
@@ -130,6 +127,9 @@ jobs:
130127
- os: macos-12
131128
python: 312
132129
platform_id: macosx_x86_64
130+
- os: macos-12
131+
python: 313
132+
platform_id: macosx_x86_64
133133

134134
steps:
135135
- uses: actions/checkout@v4
@@ -179,9 +179,6 @@ jobs:
179179
matrix:
180180
include:
181181
# MacOS 14 arm64
182-
- os: macos-14
183-
python: 38
184-
platform_id: macosx_arm64
185182
- os: macos-14
186183
python: 39
187184
platform_id: macosx_arm64
@@ -194,6 +191,9 @@ jobs:
194191
- os: macos-14
195192
python: 312
196193
platform_id: macosx_arm64
194+
- os: macos-14
195+
python: 313
196+
platform_id: macosx_arm64
197197

198198
steps:
199199
- uses: actions/checkout@v4
@@ -230,7 +230,7 @@ jobs:
230230
strategy:
231231
fail-fast: false
232232
matrix:
233-
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
233+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
234234

235235
steps:
236236
- name: Set up Python ${{ matrix.python-version }}

build.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33
from pathlib import Path
44
import shutil
5+
from struct import unpack
56
import subprocess
67
from typing import List, Any
78

@@ -24,6 +25,9 @@ def build(setup_kwargs: Any) -> Any:
2425

2526
setup_oj()
2627

28+
# Determine if system is big endian or not
29+
macros = [("ON_BE_SYSTEM")] if unpack("h", b"\x00\x01")[0] == 1 else []
30+
2731
ext = Extension(
2832
"_openjpeg",
2933
[os.fspath(p) for p in get_source_files()],
@@ -35,6 +39,7 @@ def build(setup_kwargs: Any) -> Any:
3539
],
3640
extra_compile_args=[],
3741
extra_link_args=[],
42+
define_macros=macros,
3843
)
3944

4045
ext_modules = cythonize(

lib/interface/decode.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,9 @@ extern int Decode(PyObject* fd, unsigned char *out, int codec_format)
458458
fd : PyObject *
459459
The Python stream object containing the JPEG 2000 data to be decoded.
460460
out : unsigned char *
461-
The numpy ndarray of uint8 where the decoded image data will be written
461+
Either a Python bytearray object or a numpy ndarray of uint8 to write the
462+
decoded image data to. Multi-byte decoded data will be written using little
463+
endian byte ordering.
462464
codec_format : int
463465
The format of the JPEG 2000 data, one of:
464466
* ``0`` - OPJ_CODEC_J2K : JPEG-2000 codestream
@@ -632,11 +634,18 @@ extern int Decode(PyObject* fd, unsigned char *out, int codec_format)
632634
for (ii = 0; ii < NR_COMPONENTS; ii++)
633635
{
634636
u16.val = (unsigned short)(*p_component[ii]);
635-
// Little endian output
637+
// Ensure little endian output
638+
#ifdef ON_BE_SYSTEM
639+
*out = u16.vals[1];
640+
out++;
641+
*out = u16.vals[0];
642+
out++;
643+
#else
636644
*out = u16.vals[0];
637645
out++;
638646
*out = u16.vals[1];
639647
out++;
648+
#endif
640649
p_component[ii]++;
641650
}
642651
}
@@ -655,7 +664,17 @@ extern int Decode(PyObject* fd, unsigned char *out, int codec_format)
655664
for (ii = 0; ii < NR_COMPONENTS; ii++)
656665
{
657666
u32.val = (unsigned long)(*p_component[ii]);
658-
// Little endian output
667+
// Ensure little endian output
668+
#ifdef ON_BE_SYSTEM
669+
*out = u32.vals[3];
670+
out++;
671+
*out = u32.vals[2];
672+
out++;
673+
*out = u32.vals[1];
674+
out++;
675+
*out = u32.vals[0];
676+
out++;
677+
#else
659678
*out = u32.vals[0];
660679
out++;
661680
*out = u32.vals[1];
@@ -664,6 +683,8 @@ extern int Decode(PyObject* fd, unsigned char *out, int codec_format)
664683
out++;
665684
*out = u32.vals[3];
666685
out++;
686+
#endif
687+
667688
p_component[ii]++;
668689
}
669690
}

0 commit comments

Comments
 (0)