Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/openjpeg/src/lib/openjp2/sparse_array.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* | |
| 2 * The copyright in this software is being made available under the 2-clauses | |
| 3 * BSD License, included below. This software may be subject to other third | |
| 4 * party and contributor rights, including patent rights, and no such rights | |
| 5 * are granted under this license. | |
| 6 * | |
| 7 * Copyright (c) 2017, IntoPix SA <contact@intopix.com> | |
| 8 * All rights reserved. | |
| 9 * | |
| 10 * Redistribution and use in source and binary forms, with or without | |
| 11 * modification, are permitted provided that the following conditions | |
| 12 * are met: | |
| 13 * 1. Redistributions of source code must retain the above copyright | |
| 14 * notice, this list of conditions and the following disclaimer. | |
| 15 * 2. Redistributions in binary form must reproduce the above copyright | |
| 16 * notice, this list of conditions and the following disclaimer in the | |
| 17 * documentation and/or other materials provided with the distribution. | |
| 18 * | |
| 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' | |
| 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
| 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
| 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 29 * POSSIBILITY OF SUCH DAMAGE. | |
| 30 */ | |
| 31 | |
| 32 #include "opj_includes.h" | |
| 33 | |
| 34 | |
| 35 struct opj_sparse_array_int32 { | |
| 36 OPJ_UINT32 width; | |
| 37 OPJ_UINT32 height; | |
| 38 OPJ_UINT32 block_width; | |
| 39 OPJ_UINT32 block_height; | |
| 40 OPJ_UINT32 block_count_hor; | |
| 41 OPJ_UINT32 block_count_ver; | |
| 42 OPJ_INT32** data_blocks; | |
| 43 }; | |
| 44 | |
| 45 opj_sparse_array_int32_t* opj_sparse_array_int32_create(OPJ_UINT32 width, | |
| 46 OPJ_UINT32 height, | |
| 47 OPJ_UINT32 block_width, | |
| 48 OPJ_UINT32 block_height) | |
| 49 { | |
| 50 opj_sparse_array_int32_t* sa; | |
| 51 | |
| 52 if (width == 0 || height == 0 || block_width == 0 || block_height == 0) { | |
| 53 return NULL; | |
| 54 } | |
| 55 if (block_width > ((OPJ_UINT32)~0U) / block_height / sizeof(OPJ_INT32)) { | |
| 56 return NULL; | |
| 57 } | |
| 58 | |
| 59 sa = (opj_sparse_array_int32_t*) opj_calloc(1, | |
| 60 sizeof(opj_sparse_array_int32_t)); | |
| 61 sa->width = width; | |
| 62 sa->height = height; | |
| 63 sa->block_width = block_width; | |
| 64 sa->block_height = block_height; | |
| 65 sa->block_count_hor = opj_uint_ceildiv(width, block_width); | |
| 66 sa->block_count_ver = opj_uint_ceildiv(height, block_height); | |
| 67 if (sa->block_count_hor > ((OPJ_UINT32)~0U) / sa->block_count_ver) { | |
| 68 opj_free(sa); | |
| 69 return NULL; | |
| 70 } | |
| 71 sa->data_blocks = (OPJ_INT32**) opj_calloc(sizeof(OPJ_INT32*), | |
| 72 (size_t) sa->block_count_hor * sa->block_count_ver); | |
| 73 if (sa->data_blocks == NULL) { | |
| 74 opj_free(sa); | |
| 75 return NULL; | |
| 76 } | |
| 77 | |
| 78 return sa; | |
| 79 } | |
| 80 | |
| 81 void opj_sparse_array_int32_free(opj_sparse_array_int32_t* sa) | |
| 82 { | |
| 83 if (sa) { | |
| 84 OPJ_UINT32 i; | |
| 85 for (i = 0; i < sa->block_count_hor * sa->block_count_ver; i++) { | |
| 86 if (sa->data_blocks[i]) { | |
| 87 opj_free(sa->data_blocks[i]); | |
| 88 } | |
| 89 } | |
| 90 opj_free(sa->data_blocks); | |
| 91 opj_free(sa); | |
| 92 } | |
| 93 } | |
| 94 | |
| 95 OPJ_BOOL opj_sparse_array_is_region_valid(const opj_sparse_array_int32_t* sa, | |
| 96 OPJ_UINT32 x0, | |
| 97 OPJ_UINT32 y0, | |
| 98 OPJ_UINT32 x1, | |
| 99 OPJ_UINT32 y1) | |
| 100 { | |
| 101 return !(x0 >= sa->width || x1 <= x0 || x1 > sa->width || | |
| 102 y0 >= sa->height || y1 <= y0 || y1 > sa->height); | |
| 103 } | |
| 104 | |
| 105 static OPJ_BOOL opj_sparse_array_int32_read_or_write( | |
| 106 const opj_sparse_array_int32_t* sa, | |
| 107 OPJ_UINT32 x0, | |
| 108 OPJ_UINT32 y0, | |
| 109 OPJ_UINT32 x1, | |
| 110 OPJ_UINT32 y1, | |
| 111 OPJ_INT32* buf, | |
| 112 OPJ_UINT32 buf_col_stride, | |
| 113 OPJ_UINT32 buf_line_stride, | |
| 114 OPJ_BOOL forgiving, | |
| 115 OPJ_BOOL is_read_op) | |
| 116 { | |
| 117 OPJ_UINT32 y, block_y; | |
| 118 OPJ_UINT32 y_incr = 0; | |
| 119 const OPJ_UINT32 block_width = sa->block_width; | |
| 120 | |
| 121 if (!opj_sparse_array_is_region_valid(sa, x0, y0, x1, y1)) { | |
| 122 return forgiving; | |
| 123 } | |
| 124 | |
| 125 block_y = y0 / sa->block_height; | |
| 126 for (y = y0; y < y1; block_y ++, y += y_incr) { | |
| 127 OPJ_UINT32 x, block_x; | |
| 128 OPJ_UINT32 x_incr = 0; | |
| 129 OPJ_UINT32 block_y_offset; | |
| 130 y_incr = (y == y0) ? sa->block_height - (y0 % sa->block_height) : | |
| 131 sa->block_height; | |
| 132 block_y_offset = sa->block_height - y_incr; | |
| 133 y_incr = opj_uint_min(y_incr, y1 - y); | |
| 134 block_x = x0 / block_width; | |
| 135 for (x = x0; x < x1; block_x ++, x += x_incr) { | |
| 136 OPJ_UINT32 j; | |
| 137 OPJ_UINT32 block_x_offset; | |
| 138 OPJ_INT32* src_block; | |
| 139 x_incr = (x == x0) ? block_width - (x0 % block_width) : block_width; | |
| 140 block_x_offset = block_width - x_incr; | |
| 141 x_incr = opj_uint_min(x_incr, x1 - x); | |
| 142 src_block = sa->data_blocks[block_y * sa->block_count_hor + block_x]; | |
| 143 if (is_read_op) { | |
| 144 if (src_block == NULL) { | |
| 145 if (buf_col_stride == 1) { | |
| 146 OPJ_INT32* dest_ptr = buf + (y - y0) * (OPJ_SIZE_T)buf_line_stride + | |
| 147 (x - x0) * buf_col_stride; | |
| 148 for (j = 0; j < y_incr; j++) { | |
| 149 memset(dest_ptr, 0, sizeof(OPJ_INT32) * x_incr); | |
| 150 dest_ptr += buf_line_stride; | |
| 151 } | |
| 152 } else { | |
| 153 OPJ_INT32* dest_ptr = buf + (y - y0) * (OPJ_SIZE_T)buf_line_stride + | |
| 154 (x - x0) * buf_col_stride; | |
| 155 for (j = 0; j < y_incr; j++) { | |
| 156 OPJ_UINT32 k; | |
| 157 for (k = 0; k < x_incr; k++) { | |
| 158 dest_ptr[k * buf_col_stride] = 0; | |
| 159 } | |
| 160 dest_ptr += buf_line_stride; | |
| 161 } | |
| 162 } | |
| 163 } else { | |
| 164 const OPJ_INT32* OPJ_RESTRICT src_ptr = src_block + block_y_offset * | |
| 165 (OPJ_SIZE_T)block_width + block_x_offset; | |
| 166 if (buf_col_stride == 1) { | |
| 167 OPJ_INT32* OPJ_RESTRICT dest_ptr = buf + (y - y0) * (OPJ_SIZE_T)buf_line_stride | |
| 168 + | |
| 169 (x - x0) * buf_col_stride; | |
| 170 if (x_incr == 4) { | |
| 171 /* Same code as general branch, but the compiler */ | |
| 172 /* can have an efficient memcpy() */ | |
| 173 (void)(x_incr); /* trick to silent cppcheck duplicateBranch warning */ | |
| 174 for (j = 0; j < y_incr; j++) { | |
| 175 memcpy(dest_ptr, src_ptr, sizeof(OPJ_INT32) * x_incr); | |
| 176 dest_ptr += buf_line_stride; | |
| 177 src_ptr += block_width; | |
| 178 } | |
| 179 } else { | |
| 180 for (j = 0; j < y_incr; j++) { | |
| 181 memcpy(dest_ptr, src_ptr, sizeof(OPJ_INT32) * x_incr); | |
| 182 dest_ptr += buf_line_stride; | |
| 183 src_ptr += block_width; | |
| 184 } | |
| 185 } | |
| 186 } else { | |
| 187 OPJ_INT32* OPJ_RESTRICT dest_ptr = buf + (y - y0) * (OPJ_SIZE_T)buf_line_stride | |
| 188 + | |
| 189 (x - x0) * buf_col_stride; | |
| 190 if (x_incr == 1) { | |
| 191 for (j = 0; j < y_incr; j++) { | |
| 192 *dest_ptr = *src_ptr; | |
| 193 dest_ptr += buf_line_stride; | |
| 194 src_ptr += block_width; | |
| 195 } | |
| 196 } else if (y_incr == 1 && buf_col_stride == 2) { | |
| 197 OPJ_UINT32 k; | |
| 198 for (k = 0; k < (x_incr & ~3U); k += 4) { | |
| 199 dest_ptr[k * buf_col_stride] = src_ptr[k]; | |
| 200 dest_ptr[(k + 1) * buf_col_stride] = src_ptr[k + 1]; | |
| 201 dest_ptr[(k + 2) * buf_col_stride] = src_ptr[k + 2]; | |
| 202 dest_ptr[(k + 3) * buf_col_stride] = src_ptr[k + 3]; | |
| 203 } | |
| 204 for (; k < x_incr; k++) { | |
| 205 dest_ptr[k * buf_col_stride] = src_ptr[k]; | |
| 206 } | |
| 207 } else if (x_incr >= 8 && buf_col_stride == 8) { | |
| 208 for (j = 0; j < y_incr; j++) { | |
| 209 OPJ_UINT32 k; | |
| 210 for (k = 0; k < (x_incr & ~3U); k += 4) { | |
| 211 dest_ptr[k * buf_col_stride] = src_ptr[k]; | |
| 212 dest_ptr[(k + 1) * buf_col_stride] = src_ptr[k + 1]; | |
| 213 dest_ptr[(k + 2) * buf_col_stride] = src_ptr[k + 2]; | |
| 214 dest_ptr[(k + 3) * buf_col_stride] = src_ptr[k + 3]; | |
| 215 } | |
| 216 for (; k < x_incr; k++) { | |
| 217 dest_ptr[k * buf_col_stride] = src_ptr[k]; | |
| 218 } | |
| 219 dest_ptr += buf_line_stride; | |
| 220 src_ptr += block_width; | |
| 221 } | |
| 222 } else { | |
| 223 /* General case */ | |
| 224 for (j = 0; j < y_incr; j++) { | |
| 225 OPJ_UINT32 k; | |
| 226 for (k = 0; k < x_incr; k++) { | |
| 227 dest_ptr[k * buf_col_stride] = src_ptr[k]; | |
| 228 } | |
| 229 dest_ptr += buf_line_stride; | |
| 230 src_ptr += block_width; | |
| 231 } | |
| 232 } | |
| 233 } | |
| 234 } | |
| 235 } else { | |
| 236 if (src_block == NULL) { | |
| 237 src_block = (OPJ_INT32*) opj_calloc(1, | |
| 238 (size_t) sa->block_width * sa->block_height * sizeof(OPJ_INT32)); | |
| 239 if (src_block == NULL) { | |
| 240 return OPJ_FALSE; | |
| 241 } | |
| 242 sa->data_blocks[block_y * sa->block_count_hor + block_x] = src_block; | |
| 243 } | |
| 244 | |
| 245 if (buf_col_stride == 1) { | |
| 246 OPJ_INT32* OPJ_RESTRICT dest_ptr = src_block + block_y_offset * | |
| 247 (OPJ_SIZE_T)block_width + block_x_offset; | |
| 248 const OPJ_INT32* OPJ_RESTRICT src_ptr = buf + (y - y0) * | |
| 249 (OPJ_SIZE_T)buf_line_stride + (x - x0) * buf_col_stride; | |
| 250 if (x_incr == 4) { | |
| 251 /* Same code as general branch, but the compiler */ | |
| 252 /* can have an efficient memcpy() */ | |
| 253 (void)(x_incr); /* trick to silent cppcheck duplicateBranch warning */ | |
| 254 for (j = 0; j < y_incr; j++) { | |
| 255 memcpy(dest_ptr, src_ptr, sizeof(OPJ_INT32) * x_incr); | |
| 256 dest_ptr += block_width; | |
| 257 src_ptr += buf_line_stride; | |
| 258 } | |
| 259 } else { | |
| 260 for (j = 0; j < y_incr; j++) { | |
| 261 memcpy(dest_ptr, src_ptr, sizeof(OPJ_INT32) * x_incr); | |
| 262 dest_ptr += block_width; | |
| 263 src_ptr += buf_line_stride; | |
| 264 } | |
| 265 } | |
| 266 } else { | |
| 267 OPJ_INT32* OPJ_RESTRICT dest_ptr = src_block + block_y_offset * | |
| 268 (OPJ_SIZE_T)block_width + block_x_offset; | |
| 269 const OPJ_INT32* OPJ_RESTRICT src_ptr = buf + (y - y0) * | |
| 270 (OPJ_SIZE_T)buf_line_stride + (x - x0) * buf_col_stride; | |
| 271 if (x_incr == 1) { | |
| 272 for (j = 0; j < y_incr; j++) { | |
| 273 *dest_ptr = *src_ptr; | |
| 274 src_ptr += buf_line_stride; | |
| 275 dest_ptr += block_width; | |
| 276 } | |
| 277 } else if (x_incr >= 8 && buf_col_stride == 8) { | |
| 278 for (j = 0; j < y_incr; j++) { | |
| 279 OPJ_UINT32 k; | |
| 280 for (k = 0; k < (x_incr & ~3U); k += 4) { | |
| 281 dest_ptr[k] = src_ptr[k * buf_col_stride]; | |
| 282 dest_ptr[k + 1] = src_ptr[(k + 1) * buf_col_stride]; | |
| 283 dest_ptr[k + 2] = src_ptr[(k + 2) * buf_col_stride]; | |
| 284 dest_ptr[k + 3] = src_ptr[(k + 3) * buf_col_stride]; | |
| 285 } | |
| 286 for (; k < x_incr; k++) { | |
| 287 dest_ptr[k] = src_ptr[k * buf_col_stride]; | |
| 288 } | |
| 289 src_ptr += buf_line_stride; | |
| 290 dest_ptr += block_width; | |
| 291 } | |
| 292 } else { | |
| 293 /* General case */ | |
| 294 for (j = 0; j < y_incr; j++) { | |
| 295 OPJ_UINT32 k; | |
| 296 for (k = 0; k < x_incr; k++) { | |
| 297 dest_ptr[k] = src_ptr[k * buf_col_stride]; | |
| 298 } | |
| 299 src_ptr += buf_line_stride; | |
| 300 dest_ptr += block_width; | |
| 301 } | |
| 302 } | |
| 303 } | |
| 304 } | |
| 305 } | |
| 306 } | |
| 307 | |
| 308 return OPJ_TRUE; | |
| 309 } | |
| 310 | |
| 311 OPJ_BOOL opj_sparse_array_int32_read(const opj_sparse_array_int32_t* sa, | |
| 312 OPJ_UINT32 x0, | |
| 313 OPJ_UINT32 y0, | |
| 314 OPJ_UINT32 x1, | |
| 315 OPJ_UINT32 y1, | |
| 316 OPJ_INT32* dest, | |
| 317 OPJ_UINT32 dest_col_stride, | |
| 318 OPJ_UINT32 dest_line_stride, | |
| 319 OPJ_BOOL forgiving) | |
| 320 { | |
| 321 return opj_sparse_array_int32_read_or_write( | |
| 322 (opj_sparse_array_int32_t*)sa, x0, y0, x1, y1, | |
| 323 dest, | |
| 324 dest_col_stride, | |
| 325 dest_line_stride, | |
| 326 forgiving, | |
| 327 OPJ_TRUE); | |
| 328 } | |
| 329 | |
| 330 OPJ_BOOL opj_sparse_array_int32_write(opj_sparse_array_int32_t* sa, | |
| 331 OPJ_UINT32 x0, | |
| 332 OPJ_UINT32 y0, | |
| 333 OPJ_UINT32 x1, | |
| 334 OPJ_UINT32 y1, | |
| 335 const OPJ_INT32* src, | |
| 336 OPJ_UINT32 src_col_stride, | |
| 337 OPJ_UINT32 src_line_stride, | |
| 338 OPJ_BOOL forgiving) | |
| 339 { | |
| 340 return opj_sparse_array_int32_read_or_write(sa, x0, y0, x1, y1, | |
| 341 (OPJ_INT32*)src, | |
| 342 src_col_stride, | |
| 343 src_line_stride, | |
| 344 forgiving, | |
| 345 OPJ_FALSE); | |
| 346 } |
