Storage.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. /*
  2. * The Python Imaging Library
  3. * $Id$
  4. *
  5. * imaging storage object
  6. *
  7. * This baseline implementation is designed to efficiently handle
  8. * large images, provided they fit into the available memory.
  9. *
  10. * history:
  11. * 1995-06-15 fl Created
  12. * 1995-09-12 fl Updated API, compiles silently under ANSI C++
  13. * 1995-11-26 fl Compiles silently under Borland 4.5 as well
  14. * 1996-05-05 fl Correctly test status from Prologue
  15. * 1997-05-12 fl Increased THRESHOLD (to speed up Tk interface)
  16. * 1997-05-30 fl Added support for floating point images
  17. * 1997-11-17 fl Added support for "RGBX" images
  18. * 1998-01-11 fl Added support for integer images
  19. * 1998-03-05 fl Exported Prologue/Epilogue functions
  20. * 1998-07-01 fl Added basic "YCrCb" support
  21. * 1998-07-03 fl Attach palette in prologue for "P" images
  22. * 1998-07-09 hk Don't report MemoryError on zero-size images
  23. * 1998-07-12 fl Change "YCrCb" to "YCbCr" (!)
  24. * 1998-10-26 fl Added "I;16" and "I;16B" storage modes (experimental)
  25. * 1998-12-29 fl Fixed allocation bug caused by previous fix
  26. * 1999-02-03 fl Added "RGBa" and "BGR" modes (experimental)
  27. * 2001-04-22 fl Fixed potential memory leak in ImagingCopyPalette
  28. * 2003-09-26 fl Added "LA" and "PA" modes (experimental)
  29. * 2005-10-02 fl Added image counter
  30. *
  31. * Copyright (c) 1998-2005 by Secret Labs AB
  32. * Copyright (c) 1995-2005 by Fredrik Lundh
  33. *
  34. * See the README file for information on usage and redistribution.
  35. */
  36. #include "Imaging.h"
  37. #include <string.h>
  38. /* --------------------------------------------------------------------
  39. * Standard image object.
  40. */
  41. Imaging
  42. ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
  43. Imaging im;
  44. /* linesize overflow check, roughly the current largest space req'd */
  45. if (xsize > (INT_MAX / 4) - 1) {
  46. return (Imaging)ImagingError_MemoryError();
  47. }
  48. im = (Imaging)calloc(1, size);
  49. if (!im) {
  50. return (Imaging)ImagingError_MemoryError();
  51. }
  52. /* Setup image descriptor */
  53. im->xsize = xsize;
  54. im->ysize = ysize;
  55. im->type = IMAGING_TYPE_UINT8;
  56. if (strcmp(mode, "1") == 0) {
  57. /* 1-bit images */
  58. im->bands = im->pixelsize = 1;
  59. im->linesize = xsize;
  60. } else if (strcmp(mode, "P") == 0) {
  61. /* 8-bit palette mapped images */
  62. im->bands = im->pixelsize = 1;
  63. im->linesize = xsize;
  64. im->palette = ImagingPaletteNew("RGB");
  65. } else if (strcmp(mode, "PA") == 0) {
  66. /* 8-bit palette with alpha */
  67. im->bands = 2;
  68. im->pixelsize = 4; /* store in image32 memory */
  69. im->linesize = xsize * 4;
  70. im->palette = ImagingPaletteNew("RGB");
  71. } else if (strcmp(mode, "L") == 0) {
  72. /* 8-bit grayscale (luminance) images */
  73. im->bands = im->pixelsize = 1;
  74. im->linesize = xsize;
  75. } else if (strcmp(mode, "LA") == 0) {
  76. /* 8-bit grayscale (luminance) with alpha */
  77. im->bands = 2;
  78. im->pixelsize = 4; /* store in image32 memory */
  79. im->linesize = xsize * 4;
  80. } else if (strcmp(mode, "La") == 0) {
  81. /* 8-bit grayscale (luminance) with premultiplied alpha */
  82. im->bands = 2;
  83. im->pixelsize = 4; /* store in image32 memory */
  84. im->linesize = xsize * 4;
  85. } else if (strcmp(mode, "F") == 0) {
  86. /* 32-bit floating point images */
  87. im->bands = 1;
  88. im->pixelsize = 4;
  89. im->linesize = xsize * 4;
  90. im->type = IMAGING_TYPE_FLOAT32;
  91. } else if (strcmp(mode, "I") == 0) {
  92. /* 32-bit integer images */
  93. im->bands = 1;
  94. im->pixelsize = 4;
  95. im->linesize = xsize * 4;
  96. im->type = IMAGING_TYPE_INT32;
  97. } else if (
  98. strcmp(mode, "I;16") == 0 || strcmp(mode, "I;16L") == 0 ||
  99. strcmp(mode, "I;16B") == 0 || strcmp(mode, "I;16N") == 0) {
  100. /* EXPERIMENTAL */
  101. /* 16-bit raw integer images */
  102. im->bands = 1;
  103. im->pixelsize = 2;
  104. im->linesize = xsize * 2;
  105. im->type = IMAGING_TYPE_SPECIAL;
  106. } else if (strcmp(mode, "RGB") == 0) {
  107. /* 24-bit true colour images */
  108. im->bands = 3;
  109. im->pixelsize = 4;
  110. im->linesize = xsize * 4;
  111. } else if (strcmp(mode, "BGR;15") == 0) {
  112. /* EXPERIMENTAL */
  113. /* 15-bit reversed true colour */
  114. im->bands = 3;
  115. im->pixelsize = 2;
  116. im->linesize = (xsize * 2 + 3) & -4;
  117. im->type = IMAGING_TYPE_SPECIAL;
  118. } else if (strcmp(mode, "BGR;16") == 0) {
  119. /* EXPERIMENTAL */
  120. /* 16-bit reversed true colour */
  121. im->bands = 3;
  122. im->pixelsize = 2;
  123. im->linesize = (xsize * 2 + 3) & -4;
  124. im->type = IMAGING_TYPE_SPECIAL;
  125. } else if (strcmp(mode, "BGR;24") == 0) {
  126. /* EXPERIMENTAL */
  127. /* 24-bit reversed true colour */
  128. im->bands = 3;
  129. im->pixelsize = 3;
  130. im->linesize = (xsize * 3 + 3) & -4;
  131. im->type = IMAGING_TYPE_SPECIAL;
  132. } else if (strcmp(mode, "RGBX") == 0) {
  133. /* 32-bit true colour images with padding */
  134. im->bands = im->pixelsize = 4;
  135. im->linesize = xsize * 4;
  136. } else if (strcmp(mode, "RGBA") == 0) {
  137. /* 32-bit true colour images with alpha */
  138. im->bands = im->pixelsize = 4;
  139. im->linesize = xsize * 4;
  140. } else if (strcmp(mode, "RGBa") == 0) {
  141. /* 32-bit true colour images with premultiplied alpha */
  142. im->bands = im->pixelsize = 4;
  143. im->linesize = xsize * 4;
  144. } else if (strcmp(mode, "CMYK") == 0) {
  145. /* 32-bit colour separation */
  146. im->bands = im->pixelsize = 4;
  147. im->linesize = xsize * 4;
  148. } else if (strcmp(mode, "YCbCr") == 0) {
  149. /* 24-bit video format */
  150. im->bands = 3;
  151. im->pixelsize = 4;
  152. im->linesize = xsize * 4;
  153. } else if (strcmp(mode, "LAB") == 0) {
  154. /* 24-bit color, luminance, + 2 color channels */
  155. /* L is uint8, a,b are int8 */
  156. im->bands = 3;
  157. im->pixelsize = 4;
  158. im->linesize = xsize * 4;
  159. } else if (strcmp(mode, "HSV") == 0) {
  160. /* 24-bit color, luminance, + 2 color channels */
  161. /* L is uint8, a,b are int8 */
  162. im->bands = 3;
  163. im->pixelsize = 4;
  164. im->linesize = xsize * 4;
  165. } else {
  166. free(im);
  167. return (Imaging)ImagingError_ValueError("unrecognized image mode");
  168. }
  169. /* Setup image descriptor */
  170. strcpy(im->mode, mode);
  171. /* Pointer array (allocate at least one line, to avoid MemoryError
  172. exceptions on platforms where calloc(0, x) returns NULL) */
  173. im->image = (char **)calloc((ysize > 0) ? ysize : 1, sizeof(void *));
  174. if (!im->image) {
  175. free(im);
  176. return (Imaging)ImagingError_MemoryError();
  177. }
  178. /* Initialize alias pointers to pixel data. */
  179. switch (im->pixelsize) {
  180. case 1:
  181. case 2:
  182. case 3:
  183. im->image8 = (UINT8 **)im->image;
  184. break;
  185. case 4:
  186. im->image32 = (INT32 **)im->image;
  187. break;
  188. }
  189. ImagingDefaultArena.stats_new_count += 1;
  190. return im;
  191. }
  192. Imaging
  193. ImagingNewPrologue(const char *mode, int xsize, int ysize) {
  194. return ImagingNewPrologueSubtype(
  195. mode, xsize, ysize, sizeof(struct ImagingMemoryInstance));
  196. }
  197. void
  198. ImagingDelete(Imaging im) {
  199. if (!im) {
  200. return;
  201. }
  202. if (im->palette) {
  203. ImagingPaletteDelete(im->palette);
  204. }
  205. if (im->destroy) {
  206. im->destroy(im);
  207. }
  208. if (im->image) {
  209. free(im->image);
  210. }
  211. free(im);
  212. }
  213. /* Array Storage Type */
  214. /* ------------------ */
  215. /* Allocate image as an array of line buffers. */
  216. #define IMAGING_PAGE_SIZE (4096)
  217. struct ImagingMemoryArena ImagingDefaultArena = {
  218. 1, // alignment
  219. 16 * 1024 * 1024, // block_size
  220. 0, // blocks_max
  221. 0, // blocks_cached
  222. NULL, // blocks_pool
  223. 0,
  224. 0,
  225. 0,
  226. 0,
  227. 0 // Stats
  228. };
  229. int
  230. ImagingMemorySetBlocksMax(ImagingMemoryArena arena, int blocks_max) {
  231. void *p;
  232. /* Free already cached blocks */
  233. ImagingMemoryClearCache(arena, blocks_max);
  234. if (blocks_max == 0 && arena->blocks_pool != NULL) {
  235. free(arena->blocks_pool);
  236. arena->blocks_pool = NULL;
  237. } else if (arena->blocks_pool != NULL) {
  238. p = realloc(arena->blocks_pool, sizeof(*arena->blocks_pool) * blocks_max);
  239. if (!p) {
  240. // Leave previous blocks_max value
  241. return 0;
  242. }
  243. arena->blocks_pool = p;
  244. } else {
  245. arena->blocks_pool = calloc(sizeof(*arena->blocks_pool), blocks_max);
  246. if (!arena->blocks_pool) {
  247. return 0;
  248. }
  249. }
  250. arena->blocks_max = blocks_max;
  251. return 1;
  252. }
  253. void
  254. ImagingMemoryClearCache(ImagingMemoryArena arena, int new_size) {
  255. while (arena->blocks_cached > new_size) {
  256. arena->blocks_cached -= 1;
  257. free(arena->blocks_pool[arena->blocks_cached].ptr);
  258. arena->stats_freed_blocks += 1;
  259. }
  260. }
  261. ImagingMemoryBlock
  262. memory_get_block(ImagingMemoryArena arena, int requested_size, int dirty) {
  263. ImagingMemoryBlock block = {NULL, 0};
  264. if (arena->blocks_cached > 0) {
  265. // Get block from cache
  266. arena->blocks_cached -= 1;
  267. block = arena->blocks_pool[arena->blocks_cached];
  268. // Reallocate if needed
  269. if (block.size != requested_size) {
  270. block.ptr = realloc(block.ptr, requested_size);
  271. }
  272. if (!block.ptr) {
  273. // Can't allocate, free previous pointer (it is still valid)
  274. free(arena->blocks_pool[arena->blocks_cached].ptr);
  275. arena->stats_freed_blocks += 1;
  276. return block;
  277. }
  278. if (!dirty) {
  279. memset(block.ptr, 0, requested_size);
  280. }
  281. arena->stats_reused_blocks += 1;
  282. if (block.ptr != arena->blocks_pool[arena->blocks_cached].ptr) {
  283. arena->stats_reallocated_blocks += 1;
  284. }
  285. } else {
  286. if (dirty) {
  287. block.ptr = malloc(requested_size);
  288. } else {
  289. block.ptr = calloc(1, requested_size);
  290. }
  291. arena->stats_allocated_blocks += 1;
  292. }
  293. block.size = requested_size;
  294. return block;
  295. }
  296. void
  297. memory_return_block(ImagingMemoryArena arena, ImagingMemoryBlock block) {
  298. if (arena->blocks_cached < arena->blocks_max) {
  299. // Reduce block size
  300. if (block.size > arena->block_size) {
  301. block.size = arena->block_size;
  302. block.ptr = realloc(block.ptr, arena->block_size);
  303. }
  304. arena->blocks_pool[arena->blocks_cached] = block;
  305. arena->blocks_cached += 1;
  306. } else {
  307. free(block.ptr);
  308. arena->stats_freed_blocks += 1;
  309. }
  310. }
  311. static void
  312. ImagingDestroyArray(Imaging im) {
  313. int y = 0;
  314. if (im->blocks) {
  315. while (im->blocks[y].ptr) {
  316. memory_return_block(&ImagingDefaultArena, im->blocks[y]);
  317. y += 1;
  318. }
  319. free(im->blocks);
  320. }
  321. }
  322. Imaging
  323. ImagingAllocateArray(Imaging im, int dirty, int block_size) {
  324. int y, line_in_block, current_block;
  325. ImagingMemoryArena arena = &ImagingDefaultArena;
  326. ImagingMemoryBlock block = {NULL, 0};
  327. int aligned_linesize, lines_per_block, blocks_count;
  328. char *aligned_ptr = NULL;
  329. /* 0-width or 0-height image. No need to do anything */
  330. if (!im->linesize || !im->ysize) {
  331. return im;
  332. }
  333. aligned_linesize = (im->linesize + arena->alignment - 1) & -arena->alignment;
  334. lines_per_block = (block_size - (arena->alignment - 1)) / aligned_linesize;
  335. if (lines_per_block == 0) {
  336. lines_per_block = 1;
  337. }
  338. blocks_count = (im->ysize + lines_per_block - 1) / lines_per_block;
  339. // printf("NEW size: %dx%d, ls: %d, lpb: %d, blocks: %d\n",
  340. // im->xsize, im->ysize, aligned_linesize, lines_per_block, blocks_count);
  341. /* One extra pointer is always NULL */
  342. im->blocks = calloc(sizeof(*im->blocks), blocks_count + 1);
  343. if (!im->blocks) {
  344. return (Imaging)ImagingError_MemoryError();
  345. }
  346. /* Allocate image as an array of lines */
  347. line_in_block = 0;
  348. current_block = 0;
  349. for (y = 0; y < im->ysize; y++) {
  350. if (line_in_block == 0) {
  351. int required;
  352. int lines_remaining = lines_per_block;
  353. if (lines_remaining > im->ysize - y) {
  354. lines_remaining = im->ysize - y;
  355. }
  356. required = lines_remaining * aligned_linesize + arena->alignment - 1;
  357. block = memory_get_block(arena, required, dirty);
  358. if (!block.ptr) {
  359. ImagingDestroyArray(im);
  360. return (Imaging)ImagingError_MemoryError();
  361. }
  362. im->blocks[current_block] = block;
  363. /* Bulletproof code from libc _int_memalign */
  364. aligned_ptr = (char *)(
  365. ((size_t) (block.ptr + arena->alignment - 1)) &
  366. -((Py_ssize_t) arena->alignment));
  367. }
  368. im->image[y] = aligned_ptr + aligned_linesize * line_in_block;
  369. line_in_block += 1;
  370. if (line_in_block >= lines_per_block) {
  371. /* Reset counter and start new block */
  372. line_in_block = 0;
  373. current_block += 1;
  374. }
  375. }
  376. im->destroy = ImagingDestroyArray;
  377. return im;
  378. }
  379. /* Block Storage Type */
  380. /* ------------------ */
  381. /* Allocate image as a single block. */
  382. static void
  383. ImagingDestroyBlock(Imaging im) {
  384. if (im->block) {
  385. free(im->block);
  386. }
  387. }
  388. Imaging
  389. ImagingAllocateBlock(Imaging im) {
  390. Py_ssize_t y, i;
  391. /* overflow check for malloc */
  392. if (im->linesize && im->ysize > INT_MAX / im->linesize) {
  393. return (Imaging)ImagingError_MemoryError();
  394. }
  395. if (im->ysize * im->linesize <= 0) {
  396. /* some platforms return NULL for malloc(0); this fix
  397. prevents MemoryError on zero-sized images on such
  398. platforms */
  399. im->block = (char *)malloc(1);
  400. } else {
  401. /* malloc check ok, overflow check above */
  402. im->block = (char *)calloc(im->ysize, im->linesize);
  403. }
  404. if (!im->block) {
  405. return (Imaging)ImagingError_MemoryError();
  406. }
  407. for (y = i = 0; y < im->ysize; y++) {
  408. im->image[y] = im->block + i;
  409. i += im->linesize;
  410. }
  411. im->destroy = ImagingDestroyBlock;
  412. return im;
  413. }
  414. /* --------------------------------------------------------------------
  415. * Create a new, internally allocated, image.
  416. */
  417. Imaging
  418. ImagingNewInternal(const char *mode, int xsize, int ysize, int dirty) {
  419. Imaging im;
  420. if (xsize < 0 || ysize < 0) {
  421. return (Imaging)ImagingError_ValueError("bad image size");
  422. }
  423. im = ImagingNewPrologue(mode, xsize, ysize);
  424. if (!im) {
  425. return NULL;
  426. }
  427. if (ImagingAllocateArray(im, dirty, ImagingDefaultArena.block_size)) {
  428. return im;
  429. }
  430. ImagingError_Clear();
  431. // Try to allocate the image once more with smallest possible block size
  432. if (ImagingAllocateArray(im, dirty, IMAGING_PAGE_SIZE)) {
  433. return im;
  434. }
  435. ImagingDelete(im);
  436. return NULL;
  437. }
  438. Imaging
  439. ImagingNew(const char *mode, int xsize, int ysize) {
  440. return ImagingNewInternal(mode, xsize, ysize, 0);
  441. }
  442. Imaging
  443. ImagingNewDirty(const char *mode, int xsize, int ysize) {
  444. return ImagingNewInternal(mode, xsize, ysize, 1);
  445. }
  446. Imaging
  447. ImagingNewBlock(const char *mode, int xsize, int ysize) {
  448. Imaging im;
  449. if (xsize < 0 || ysize < 0) {
  450. return (Imaging)ImagingError_ValueError("bad image size");
  451. }
  452. im = ImagingNewPrologue(mode, xsize, ysize);
  453. if (!im) {
  454. return NULL;
  455. }
  456. if (ImagingAllocateBlock(im)) {
  457. return im;
  458. }
  459. ImagingDelete(im);
  460. return NULL;
  461. }
  462. Imaging
  463. ImagingNew2Dirty(const char *mode, Imaging imOut, Imaging imIn) {
  464. /* allocate or validate output image */
  465. if (imOut) {
  466. /* make sure images match */
  467. if (strcmp(imOut->mode, mode) != 0 || imOut->xsize != imIn->xsize ||
  468. imOut->ysize != imIn->ysize) {
  469. return ImagingError_Mismatch();
  470. }
  471. } else {
  472. /* create new image */
  473. imOut = ImagingNewDirty(mode, imIn->xsize, imIn->ysize);
  474. if (!imOut) {
  475. return NULL;
  476. }
  477. }
  478. return imOut;
  479. }
  480. void
  481. ImagingCopyPalette(Imaging destination, Imaging source) {
  482. if (source->palette) {
  483. if (destination->palette) {
  484. ImagingPaletteDelete(destination->palette);
  485. }
  486. destination->palette = ImagingPaletteDuplicate(source->palette);
  487. }
  488. }