Storage.c 16 KB

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