Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/openjpeg/src/lib/openjp2/bench_dwt.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 #ifdef _WIN32 | |
| 35 #include <windows.h> | |
| 36 #else | |
| 37 #include <sys/time.h> | |
| 38 #include <sys/resource.h> | |
| 39 #include <sys/times.h> | |
| 40 #endif /* _WIN32 */ | |
| 41 | |
| 42 OPJ_INT32 getValue(OPJ_UINT32 i) | |
| 43 { | |
| 44 return ((OPJ_INT32)i % 511) - 256; | |
| 45 } | |
| 46 | |
| 47 void init_tilec(opj_tcd_tilecomp_t * l_tilec, | |
| 48 OPJ_INT32 x0, | |
| 49 OPJ_INT32 y0, | |
| 50 OPJ_INT32 x1, | |
| 51 OPJ_INT32 y1, | |
| 52 OPJ_UINT32 numresolutions, | |
| 53 OPJ_BOOL irreversible) | |
| 54 { | |
| 55 opj_tcd_resolution_t* l_res; | |
| 56 OPJ_UINT32 resno, l_level_no; | |
| 57 size_t i, nValues; | |
| 58 | |
| 59 memset(l_tilec, 0, sizeof(*l_tilec)); | |
| 60 l_tilec->x0 = x0; | |
| 61 l_tilec->y0 = y0; | |
| 62 l_tilec->x1 = x1; | |
| 63 l_tilec->y1 = y1; | |
| 64 nValues = (size_t)(l_tilec->x1 - l_tilec->x0) * | |
| 65 (size_t)(l_tilec->y1 - l_tilec->y0); | |
| 66 l_tilec->data = (OPJ_INT32*) opj_malloc(sizeof(OPJ_INT32) * nValues); | |
| 67 assert(l_tilec->data != NULL); | |
| 68 for (i = 0; i < nValues; i++) { | |
| 69 OPJ_INT32 val = getValue((OPJ_UINT32)i); | |
| 70 if (irreversible) { | |
| 71 OPJ_FLOAT32 fVal = (OPJ_FLOAT32)val; | |
| 72 memcpy(&l_tilec->data[i], &fVal, sizeof(OPJ_FLOAT32)); | |
| 73 } else { | |
| 74 l_tilec->data[i] = val; | |
| 75 } | |
| 76 } | |
| 77 l_tilec->numresolutions = numresolutions; | |
| 78 l_tilec->minimum_num_resolutions = numresolutions; | |
| 79 l_tilec->resolutions = (opj_tcd_resolution_t*) opj_calloc( | |
| 80 l_tilec->numresolutions, | |
| 81 sizeof(opj_tcd_resolution_t)); | |
| 82 | |
| 83 l_level_no = l_tilec->numresolutions; | |
| 84 l_res = l_tilec->resolutions; | |
| 85 | |
| 86 /* Adapted from opj_tcd_init_tile() */ | |
| 87 for (resno = 0; resno < l_tilec->numresolutions; ++resno) { | |
| 88 | |
| 89 --l_level_no; | |
| 90 | |
| 91 /* border for each resolution level (global) */ | |
| 92 l_res->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no); | |
| 93 l_res->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no); | |
| 94 l_res->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no); | |
| 95 l_res->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no); | |
| 96 | |
| 97 ++l_res; | |
| 98 } | |
| 99 } | |
| 100 | |
| 101 void free_tilec(opj_tcd_tilecomp_t * l_tilec) | |
| 102 { | |
| 103 opj_free(l_tilec->data); | |
| 104 opj_free(l_tilec->resolutions); | |
| 105 } | |
| 106 | |
| 107 void usage(void) | |
| 108 { | |
| 109 printf( | |
| 110 "bench_dwt [-decode|encode] [-I] [-size value] [-check] [-display]\n"); | |
| 111 printf( | |
| 112 " [-num_resolutions val] [-offset x y] [-num_threads val]\n"); | |
| 113 exit(1); | |
| 114 } | |
| 115 | |
| 116 | |
| 117 OPJ_FLOAT64 opj_clock(void) | |
| 118 { | |
| 119 #ifdef _WIN32 | |
| 120 /* _WIN32: use QueryPerformance (very accurate) */ | |
| 121 LARGE_INTEGER freq, t ; | |
| 122 /* freq is the clock speed of the CPU */ | |
| 123 QueryPerformanceFrequency(&freq) ; | |
| 124 /* cout << "freq = " << ((double) freq.QuadPart) << endl; */ | |
| 125 /* t is the high resolution performance counter (see MSDN) */ | |
| 126 QueryPerformanceCounter(& t) ; | |
| 127 return freq.QuadPart ? (t.QuadPart / (OPJ_FLOAT64) freq.QuadPart) : 0 ; | |
| 128 #else | |
| 129 /* Unix or Linux: use resource usage */ | |
| 130 struct rusage t; | |
| 131 OPJ_FLOAT64 procTime; | |
| 132 /* (1) Get the rusage data structure at this moment (man getrusage) */ | |
| 133 getrusage(0, &t); | |
| 134 /* (2) What is the elapsed time ? - CPU time = User time + System time */ | |
| 135 /* (2a) Get the seconds */ | |
| 136 procTime = (OPJ_FLOAT64)(t.ru_utime.tv_sec + t.ru_stime.tv_sec); | |
| 137 /* (2b) More precisely! Get the microseconds part ! */ | |
| 138 return (procTime + (OPJ_FLOAT64)(t.ru_utime.tv_usec + t.ru_stime.tv_usec) * | |
| 139 1e-6) ; | |
| 140 #endif | |
| 141 } | |
| 142 | |
| 143 static OPJ_FLOAT64 opj_wallclock(void) | |
| 144 { | |
| 145 #ifdef _WIN32 | |
| 146 return opj_clock(); | |
| 147 #else | |
| 148 struct timeval tv; | |
| 149 gettimeofday(&tv, NULL); | |
| 150 return (OPJ_FLOAT64)tv.tv_sec + 1e-6 * (OPJ_FLOAT64)tv.tv_usec; | |
| 151 #endif | |
| 152 } | |
| 153 | |
| 154 int main(int argc, char** argv) | |
| 155 { | |
| 156 int num_threads = 0; | |
| 157 opj_tcd_t tcd; | |
| 158 opj_tcd_image_t tcd_image; | |
| 159 opj_tcd_tile_t tcd_tile; | |
| 160 opj_tcd_tilecomp_t tilec; | |
| 161 opj_image_t image; | |
| 162 opj_image_comp_t image_comp; | |
| 163 opj_thread_pool_t* tp; | |
| 164 OPJ_INT32 i, j, k; | |
| 165 OPJ_BOOL display = OPJ_FALSE; | |
| 166 OPJ_BOOL check = OPJ_FALSE; | |
| 167 OPJ_INT32 size = 16384 - 1; | |
| 168 OPJ_FLOAT64 start, stop; | |
| 169 OPJ_FLOAT64 start_wc, stop_wc; | |
| 170 OPJ_UINT32 offset_x = ((OPJ_UINT32)size + 1) / 2 - 1; | |
| 171 OPJ_UINT32 offset_y = ((OPJ_UINT32)size + 1) / 2 - 1; | |
| 172 OPJ_UINT32 num_resolutions = 6; | |
| 173 OPJ_BOOL bench_decode = OPJ_TRUE; | |
| 174 OPJ_BOOL irreversible = OPJ_FALSE; | |
| 175 | |
| 176 for (i = 1; i < argc; i++) { | |
| 177 if (strcmp(argv[i], "-encode") == 0) { | |
| 178 bench_decode = OPJ_FALSE; | |
| 179 } else if (strcmp(argv[i], "-decode") == 0) { | |
| 180 bench_decode = OPJ_TRUE; | |
| 181 } else if (strcmp(argv[i], "-display") == 0) { | |
| 182 display = OPJ_TRUE; | |
| 183 } else if (strcmp(argv[i], "-check") == 0) { | |
| 184 check = OPJ_TRUE; | |
| 185 } else if (strcmp(argv[i], "-I") == 0) { | |
| 186 irreversible = OPJ_TRUE; | |
| 187 } else if (strcmp(argv[i], "-size") == 0 && i + 1 < argc) { | |
| 188 size = atoi(argv[i + 1]); | |
| 189 i ++; | |
| 190 } else if (strcmp(argv[i], "-num_threads") == 0 && i + 1 < argc) { | |
| 191 num_threads = atoi(argv[i + 1]); | |
| 192 i ++; | |
| 193 } else if (strcmp(argv[i], "-num_resolutions") == 0 && i + 1 < argc) { | |
| 194 num_resolutions = (OPJ_UINT32)atoi(argv[i + 1]); | |
| 195 if (num_resolutions == 0 || num_resolutions > 32) { | |
| 196 fprintf(stderr, | |
| 197 "Invalid value for num_resolutions. Should be >= 1 and <= 32\n"); | |
| 198 exit(1); | |
| 199 } | |
| 200 i ++; | |
| 201 } else if (strcmp(argv[i], "-offset") == 0 && i + 2 < argc) { | |
| 202 offset_x = (OPJ_UINT32)atoi(argv[i + 1]); | |
| 203 offset_y = (OPJ_UINT32)atoi(argv[i + 2]); | |
| 204 i += 2; | |
| 205 } else { | |
| 206 usage(); | |
| 207 } | |
| 208 } | |
| 209 | |
| 210 if (irreversible && check) { | |
| 211 /* Due to irreversible inverse DWT not being symmetric of forward */ | |
| 212 /* See BUG_WEIRD_TWO_INVK in dwt.c */ | |
| 213 printf("-I and -check aren't compatible\n"); | |
| 214 exit(1); | |
| 215 } | |
| 216 | |
| 217 tp = opj_thread_pool_create(num_threads); | |
| 218 | |
| 219 init_tilec(&tilec, (OPJ_INT32)offset_x, (OPJ_INT32)offset_y, | |
| 220 (OPJ_INT32)offset_x + size, (OPJ_INT32)offset_y + size, | |
| 221 num_resolutions, irreversible); | |
| 222 | |
| 223 if (display) { | |
| 224 printf("Before\n"); | |
| 225 k = 0; | |
| 226 for (j = 0; j < tilec.y1 - tilec.y0; j++) { | |
| 227 for (i = 0; i < tilec.x1 - tilec.x0; i++) { | |
| 228 if (irreversible) { | |
| 229 printf("%f ", ((OPJ_FLOAT32*)tilec.data)[k]); | |
| 230 } else { | |
| 231 printf("%d ", tilec.data[k]); | |
| 232 } | |
| 233 k ++; | |
| 234 } | |
| 235 printf("\n"); | |
| 236 } | |
| 237 } | |
| 238 | |
| 239 memset(&tcd, 0, sizeof(tcd)); | |
| 240 tcd.thread_pool = tp; | |
| 241 tcd.whole_tile_decoding = OPJ_TRUE; | |
| 242 tcd.win_x0 = (OPJ_UINT32)tilec.x0; | |
| 243 tcd.win_y0 = (OPJ_UINT32)tilec.y0; | |
| 244 tcd.win_x1 = (OPJ_UINT32)tilec.x1; | |
| 245 tcd.win_y1 = (OPJ_UINT32)tilec.y1; | |
| 246 tcd.tcd_image = &tcd_image; | |
| 247 memset(&tcd_image, 0, sizeof(tcd_image)); | |
| 248 tcd_image.tiles = &tcd_tile; | |
| 249 memset(&tcd_tile, 0, sizeof(tcd_tile)); | |
| 250 tcd_tile.x0 = tilec.x0; | |
| 251 tcd_tile.y0 = tilec.y0; | |
| 252 tcd_tile.x1 = tilec.x1; | |
| 253 tcd_tile.y1 = tilec.y1; | |
| 254 tcd_tile.numcomps = 1; | |
| 255 tcd_tile.comps = &tilec; | |
| 256 tcd.image = ℑ | |
| 257 memset(&image, 0, sizeof(image)); | |
| 258 image.numcomps = 1; | |
| 259 image.comps = &image_comp; | |
| 260 memset(&image_comp, 0, sizeof(image_comp)); | |
| 261 image_comp.dx = 1; | |
| 262 image_comp.dy = 1; | |
| 263 | |
| 264 start = opj_clock(); | |
| 265 start_wc = opj_wallclock(); | |
| 266 if (bench_decode) { | |
| 267 if (irreversible) { | |
| 268 opj_dwt_decode_real(&tcd, &tilec, tilec.numresolutions); | |
| 269 } else { | |
| 270 opj_dwt_decode(&tcd, &tilec, tilec.numresolutions); | |
| 271 } | |
| 272 } else { | |
| 273 if (irreversible) { | |
| 274 opj_dwt_encode_real(&tcd, &tilec); | |
| 275 } else { | |
| 276 opj_dwt_encode(&tcd, &tilec); | |
| 277 } | |
| 278 } | |
| 279 stop = opj_clock(); | |
| 280 stop_wc = opj_wallclock(); | |
| 281 printf("time for %s: total = %.03f s, wallclock = %.03f s\n", | |
| 282 bench_decode ? "dwt_decode" : "dwt_encode", | |
| 283 stop - start, | |
| 284 stop_wc - start_wc); | |
| 285 | |
| 286 if (display) { | |
| 287 if (bench_decode) { | |
| 288 printf("After IDWT\n"); | |
| 289 } else { | |
| 290 printf("After FDWT\n"); | |
| 291 } | |
| 292 k = 0; | |
| 293 for (j = 0; j < tilec.y1 - tilec.y0; j++) { | |
| 294 for (i = 0; i < tilec.x1 - tilec.x0; i++) { | |
| 295 if (irreversible) { | |
| 296 printf("%f ", ((OPJ_FLOAT32*)tilec.data)[k]); | |
| 297 } else { | |
| 298 printf("%d ", tilec.data[k]); | |
| 299 } | |
| 300 k ++; | |
| 301 } | |
| 302 printf("\n"); | |
| 303 } | |
| 304 } | |
| 305 | |
| 306 if ((display || check) && !irreversible) { | |
| 307 | |
| 308 if (bench_decode) { | |
| 309 opj_dwt_encode(&tcd, &tilec); | |
| 310 } else { | |
| 311 opj_dwt_decode(&tcd, &tilec, tilec.numresolutions); | |
| 312 } | |
| 313 | |
| 314 | |
| 315 if (display && !irreversible) { | |
| 316 if (bench_decode) { | |
| 317 printf("After FDWT\n"); | |
| 318 } else { | |
| 319 printf("After IDWT\n"); | |
| 320 } | |
| 321 k = 0; | |
| 322 for (j = 0; j < tilec.y1 - tilec.y0; j++) { | |
| 323 for (i = 0; i < tilec.x1 - tilec.x0; i++) { | |
| 324 if (irreversible) { | |
| 325 printf("%f ", ((OPJ_FLOAT32*)tilec.data)[k]); | |
| 326 } else { | |
| 327 printf("%d ", tilec.data[k]); | |
| 328 } | |
| 329 k ++; | |
| 330 } | |
| 331 printf("\n"); | |
| 332 } | |
| 333 } | |
| 334 | |
| 335 } | |
| 336 | |
| 337 if (check) { | |
| 338 | |
| 339 size_t idx; | |
| 340 size_t nValues = (size_t)(tilec.x1 - tilec.x0) * | |
| 341 (size_t)(tilec.y1 - tilec.y0); | |
| 342 for (idx = 0; idx < nValues; idx++) { | |
| 343 if (tilec.data[idx] != getValue((OPJ_UINT32)idx)) { | |
| 344 printf("Difference found at idx = %u\n", (OPJ_UINT32)idx); | |
| 345 exit(1); | |
| 346 } | |
| 347 } | |
| 348 } | |
| 349 | |
| 350 free_tilec(&tilec); | |
| 351 | |
| 352 opj_thread_pool_destroy(tp); | |
| 353 return 0; | |
| 354 } |
