PageRenderTime 54ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/transupp.c

https://gitlab.com/ImageMagick/jpeg-turbo
C | 1628 lines | 1179 code | 107 blank | 342 comment | 343 complexity | a2dbf98f13164b1c3f08aee880c47060 MD5 | raw file
Possible License(s): BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * transupp.c
  3. *
  4. * This file was part of the Independent JPEG Group's software:
  5. * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
  6. * libjpeg-turbo Modifications:
  7. * Copyright (C) 2010, 2017, D. R. Commander.
  8. * For conditions of distribution and use, see the accompanying README.ijg
  9. * file.
  10. *
  11. * This file contains image transformation routines and other utility code
  12. * used by the jpegtran sample application. These are NOT part of the core
  13. * JPEG library. But we keep these routines separate from jpegtran.c to
  14. * ease the task of maintaining jpegtran-like programs that have other user
  15. * interfaces.
  16. */
  17. /* Although this file really shouldn't have access to the library internals,
  18. * it's helpful to let it call jround_up() and jcopy_block_row().
  19. */
  20. #define JPEG_INTERNALS
  21. #include "jinclude.h"
  22. #include "jpeglib.h"
  23. #include "transupp.h" /* My own external interface */
  24. #include "jpegcomp.h"
  25. #include <ctype.h> /* to declare isdigit() */
  26. #if JPEG_LIB_VERSION >= 70
  27. #define dstinfo_min_DCT_h_scaled_size dstinfo->min_DCT_h_scaled_size
  28. #define dstinfo_min_DCT_v_scaled_size dstinfo->min_DCT_v_scaled_size
  29. #else
  30. #define dstinfo_min_DCT_h_scaled_size DCTSIZE
  31. #define dstinfo_min_DCT_v_scaled_size DCTSIZE
  32. #endif
  33. #if TRANSFORMS_SUPPORTED
  34. /*
  35. * Lossless image transformation routines. These routines work on DCT
  36. * coefficient arrays and thus do not require any lossy decompression
  37. * or recompression of the image.
  38. * Thanks to Guido Vollbeding for the initial design and code of this feature,
  39. * and to Ben Jackson for introducing the cropping feature.
  40. *
  41. * Horizontal flipping is done in-place, using a single top-to-bottom
  42. * pass through the virtual source array. It will thus be much the
  43. * fastest option for images larger than main memory.
  44. *
  45. * The other routines require a set of destination virtual arrays, so they
  46. * need twice as much memory as jpegtran normally does. The destination
  47. * arrays are always written in normal scan order (top to bottom) because
  48. * the virtual array manager expects this. The source arrays will be scanned
  49. * in the corresponding order, which means multiple passes through the source
  50. * arrays for most of the transforms. That could result in much thrashing
  51. * if the image is larger than main memory.
  52. *
  53. * If cropping or trimming is involved, the destination arrays may be smaller
  54. * than the source arrays. Note it is not possible to do horizontal flip
  55. * in-place when a nonzero Y crop offset is specified, since we'd have to move
  56. * data from one block row to another but the virtual array manager doesn't
  57. * guarantee we can touch more than one row at a time. So in that case,
  58. * we have to use a separate destination array.
  59. *
  60. * Some notes about the operating environment of the individual transform
  61. * routines:
  62. * 1. Both the source and destination virtual arrays are allocated from the
  63. * source JPEG object, and therefore should be manipulated by calling the
  64. * source's memory manager.
  65. * 2. The destination's component count should be used. It may be smaller
  66. * than the source's when forcing to grayscale.
  67. * 3. Likewise the destination's sampling factors should be used. When
  68. * forcing to grayscale the destination's sampling factors will be all 1,
  69. * and we may as well take that as the effective iMCU size.
  70. * 4. When "trim" is in effect, the destination's dimensions will be the
  71. * trimmed values but the source's will be untrimmed.
  72. * 5. When "crop" is in effect, the destination's dimensions will be the
  73. * cropped values but the source's will be uncropped. Each transform
  74. * routine is responsible for picking up source data starting at the
  75. * correct X and Y offset for the crop region. (The X and Y offsets
  76. * passed to the transform routines are measured in iMCU blocks of the
  77. * destination.)
  78. * 6. All the routines assume that the source and destination buffers are
  79. * padded out to a full iMCU boundary. This is true, although for the
  80. * source buffer it is an undocumented property of jdcoefct.c.
  81. */
  82. LOCAL(void)
  83. do_crop(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
  84. JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
  85. jvirt_barray_ptr *src_coef_arrays,
  86. jvirt_barray_ptr *dst_coef_arrays)
  87. /* Crop. This is only used when no rotate/flip is requested with the crop. */
  88. {
  89. JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks;
  90. int ci, offset_y;
  91. JBLOCKARRAY src_buffer, dst_buffer;
  92. jpeg_component_info *compptr;
  93. /* We simply have to copy the right amount of data (the destination's
  94. * image size) starting at the given X and Y offsets in the source.
  95. */
  96. for (ci = 0; ci < dstinfo->num_components; ci++) {
  97. compptr = dstinfo->comp_info + ci;
  98. x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
  99. y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
  100. for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
  101. dst_blk_y += compptr->v_samp_factor) {
  102. dst_buffer = (*srcinfo->mem->access_virt_barray)
  103. ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
  104. (JDIMENSION)compptr->v_samp_factor, TRUE);
  105. src_buffer = (*srcinfo->mem->access_virt_barray)
  106. ((j_common_ptr)srcinfo, src_coef_arrays[ci],
  107. dst_blk_y + y_crop_blocks,
  108. (JDIMENSION)compptr->v_samp_factor, FALSE);
  109. for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
  110. jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
  111. dst_buffer[offset_y],
  112. compptr->width_in_blocks);
  113. }
  114. }
  115. }
  116. }
  117. LOCAL(void)
  118. do_flip_h_no_crop(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
  119. JDIMENSION x_crop_offset, jvirt_barray_ptr *src_coef_arrays)
  120. /* Horizontal flip; done in-place, so no separate dest array is required.
  121. * NB: this only works when y_crop_offset is zero.
  122. */
  123. {
  124. JDIMENSION MCU_cols, comp_width, blk_x, blk_y, x_crop_blocks;
  125. int ci, k, offset_y;
  126. JBLOCKARRAY buffer;
  127. JCOEFPTR ptr1, ptr2;
  128. JCOEF temp1, temp2;
  129. jpeg_component_info *compptr;
  130. /* Horizontal mirroring of DCT blocks is accomplished by swapping
  131. * pairs of blocks in-place. Within a DCT block, we perform horizontal
  132. * mirroring by changing the signs of odd-numbered columns.
  133. * Partial iMCUs at the right edge are left untouched.
  134. */
  135. MCU_cols = srcinfo->output_width /
  136. (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
  137. for (ci = 0; ci < dstinfo->num_components; ci++) {
  138. compptr = dstinfo->comp_info + ci;
  139. comp_width = MCU_cols * compptr->h_samp_factor;
  140. x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
  141. for (blk_y = 0; blk_y < compptr->height_in_blocks;
  142. blk_y += compptr->v_samp_factor) {
  143. buffer = (*srcinfo->mem->access_virt_barray)
  144. ((j_common_ptr)srcinfo, src_coef_arrays[ci], blk_y,
  145. (JDIMENSION)compptr->v_samp_factor, TRUE);
  146. for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
  147. /* Do the mirroring */
  148. for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
  149. ptr1 = buffer[offset_y][blk_x];
  150. ptr2 = buffer[offset_y][comp_width - blk_x - 1];
  151. /* this unrolled loop doesn't need to know which row it's on... */
  152. for (k = 0; k < DCTSIZE2; k += 2) {
  153. temp1 = *ptr1; /* swap even column */
  154. temp2 = *ptr2;
  155. *ptr1++ = temp2;
  156. *ptr2++ = temp1;
  157. temp1 = *ptr1; /* swap odd column with sign change */
  158. temp2 = *ptr2;
  159. *ptr1++ = -temp2;
  160. *ptr2++ = -temp1;
  161. }
  162. }
  163. if (x_crop_blocks > 0) {
  164. /* Now left-justify the portion of the data to be kept.
  165. * We can't use a single jcopy_block_row() call because that routine
  166. * depends on memcpy(), whose behavior is unspecified for overlapping
  167. * source and destination areas. Sigh.
  168. */
  169. for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
  170. jcopy_block_row(buffer[offset_y] + blk_x + x_crop_blocks,
  171. buffer[offset_y] + blk_x, (JDIMENSION)1);
  172. }
  173. }
  174. }
  175. }
  176. }
  177. }
  178. LOCAL(void)
  179. do_flip_h(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
  180. JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
  181. jvirt_barray_ptr *src_coef_arrays,
  182. jvirt_barray_ptr *dst_coef_arrays)
  183. /* Horizontal flip in general cropping case */
  184. {
  185. JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
  186. JDIMENSION x_crop_blocks, y_crop_blocks;
  187. int ci, k, offset_y;
  188. JBLOCKARRAY src_buffer, dst_buffer;
  189. JBLOCKROW src_row_ptr, dst_row_ptr;
  190. JCOEFPTR src_ptr, dst_ptr;
  191. jpeg_component_info *compptr;
  192. /* Here we must output into a separate array because we can't touch
  193. * different rows of a single virtual array simultaneously. Otherwise,
  194. * this is essentially the same as the routine above.
  195. */
  196. MCU_cols = srcinfo->output_width /
  197. (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
  198. for (ci = 0; ci < dstinfo->num_components; ci++) {
  199. compptr = dstinfo->comp_info + ci;
  200. comp_width = MCU_cols * compptr->h_samp_factor;
  201. x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
  202. y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
  203. for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
  204. dst_blk_y += compptr->v_samp_factor) {
  205. dst_buffer = (*srcinfo->mem->access_virt_barray)
  206. ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
  207. (JDIMENSION)compptr->v_samp_factor, TRUE);
  208. src_buffer = (*srcinfo->mem->access_virt_barray)
  209. ((j_common_ptr)srcinfo, src_coef_arrays[ci],
  210. dst_blk_y + y_crop_blocks,
  211. (JDIMENSION)compptr->v_samp_factor, FALSE);
  212. for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
  213. dst_row_ptr = dst_buffer[offset_y];
  214. src_row_ptr = src_buffer[offset_y];
  215. for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
  216. dst_blk_x++) {
  217. if (x_crop_blocks + dst_blk_x < comp_width) {
  218. /* Do the mirrorable blocks */
  219. dst_ptr = dst_row_ptr[dst_blk_x];
  220. src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
  221. /* this unrolled loop doesn't need to know which row it's on... */
  222. for (k = 0; k < DCTSIZE2; k += 2) {
  223. *dst_ptr++ = *src_ptr++; /* copy even column */
  224. *dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */
  225. }
  226. } else {
  227. /* Copy last partial block(s) verbatim */
  228. jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
  229. dst_row_ptr + dst_blk_x, (JDIMENSION)1);
  230. }
  231. }
  232. }
  233. }
  234. }
  235. }
  236. LOCAL(void)
  237. do_flip_v(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
  238. JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
  239. jvirt_barray_ptr *src_coef_arrays,
  240. jvirt_barray_ptr *dst_coef_arrays)
  241. /* Vertical flip */
  242. {
  243. JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
  244. JDIMENSION x_crop_blocks, y_crop_blocks;
  245. int ci, i, j, offset_y;
  246. JBLOCKARRAY src_buffer, dst_buffer;
  247. JBLOCKROW src_row_ptr, dst_row_ptr;
  248. JCOEFPTR src_ptr, dst_ptr;
  249. jpeg_component_info *compptr;
  250. /* We output into a separate array because we can't touch different
  251. * rows of the source virtual array simultaneously. Otherwise, this
  252. * is a pretty straightforward analog of horizontal flip.
  253. * Within a DCT block, vertical mirroring is done by changing the signs
  254. * of odd-numbered rows.
  255. * Partial iMCUs at the bottom edge are copied verbatim.
  256. */
  257. MCU_rows = srcinfo->output_height /
  258. (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
  259. for (ci = 0; ci < dstinfo->num_components; ci++) {
  260. compptr = dstinfo->comp_info + ci;
  261. comp_height = MCU_rows * compptr->v_samp_factor;
  262. x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
  263. y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
  264. for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
  265. dst_blk_y += compptr->v_samp_factor) {
  266. dst_buffer = (*srcinfo->mem->access_virt_barray)
  267. ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
  268. (JDIMENSION)compptr->v_samp_factor, TRUE);
  269. if (y_crop_blocks + dst_blk_y < comp_height) {
  270. /* Row is within the mirrorable area. */
  271. src_buffer = (*srcinfo->mem->access_virt_barray)
  272. ((j_common_ptr)srcinfo, src_coef_arrays[ci],
  273. comp_height - y_crop_blocks - dst_blk_y -
  274. (JDIMENSION)compptr->v_samp_factor,
  275. (JDIMENSION)compptr->v_samp_factor, FALSE);
  276. } else {
  277. /* Bottom-edge blocks will be copied verbatim. */
  278. src_buffer = (*srcinfo->mem->access_virt_barray)
  279. ((j_common_ptr)srcinfo, src_coef_arrays[ci],
  280. dst_blk_y + y_crop_blocks,
  281. (JDIMENSION)compptr->v_samp_factor, FALSE);
  282. }
  283. for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
  284. if (y_crop_blocks + dst_blk_y < comp_height) {
  285. /* Row is within the mirrorable area. */
  286. dst_row_ptr = dst_buffer[offset_y];
  287. src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
  288. src_row_ptr += x_crop_blocks;
  289. for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
  290. dst_blk_x++) {
  291. dst_ptr = dst_row_ptr[dst_blk_x];
  292. src_ptr = src_row_ptr[dst_blk_x];
  293. for (i = 0; i < DCTSIZE; i += 2) {
  294. /* copy even row */
  295. for (j = 0; j < DCTSIZE; j++)
  296. *dst_ptr++ = *src_ptr++;
  297. /* copy odd row with sign change */
  298. for (j = 0; j < DCTSIZE; j++)
  299. *dst_ptr++ = - *src_ptr++;
  300. }
  301. }
  302. } else {
  303. /* Just copy row verbatim. */
  304. jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
  305. dst_buffer[offset_y],
  306. compptr->width_in_blocks);
  307. }
  308. }
  309. }
  310. }
  311. }
  312. LOCAL(void)
  313. do_transpose(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
  314. JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
  315. jvirt_barray_ptr *src_coef_arrays,
  316. jvirt_barray_ptr *dst_coef_arrays)
  317. /* Transpose source into destination */
  318. {
  319. JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks;
  320. int ci, i, j, offset_x, offset_y;
  321. JBLOCKARRAY src_buffer, dst_buffer;
  322. JCOEFPTR src_ptr, dst_ptr;
  323. jpeg_component_info *compptr;
  324. /* Transposing pixels within a block just requires transposing the
  325. * DCT coefficients.
  326. * Partial iMCUs at the edges require no special treatment; we simply
  327. * process all the available DCT blocks for every component.
  328. */
  329. for (ci = 0; ci < dstinfo->num_components; ci++) {
  330. compptr = dstinfo->comp_info + ci;
  331. x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
  332. y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
  333. for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
  334. dst_blk_y += compptr->v_samp_factor) {
  335. dst_buffer = (*srcinfo->mem->access_virt_barray)
  336. ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
  337. (JDIMENSION)compptr->v_samp_factor, TRUE);
  338. for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
  339. for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
  340. dst_blk_x += compptr->h_samp_factor) {
  341. src_buffer = (*srcinfo->mem->access_virt_barray)
  342. ((j_common_ptr)srcinfo, src_coef_arrays[ci],
  343. dst_blk_x + x_crop_blocks,
  344. (JDIMENSION)compptr->h_samp_factor, FALSE);
  345. for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
  346. dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
  347. src_ptr =
  348. src_buffer[offset_x][dst_blk_y + offset_y + y_crop_blocks];
  349. for (i = 0; i < DCTSIZE; i++)
  350. for (j = 0; j < DCTSIZE; j++)
  351. dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
  352. }
  353. }
  354. }
  355. }
  356. }
  357. }
  358. LOCAL(void)
  359. do_rot_90(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
  360. JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
  361. jvirt_barray_ptr *src_coef_arrays,
  362. jvirt_barray_ptr *dst_coef_arrays)
  363. /* 90 degree rotation is equivalent to
  364. * 1. Transposing the image;
  365. * 2. Horizontal mirroring.
  366. * These two steps are merged into a single processing routine.
  367. */
  368. {
  369. JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
  370. JDIMENSION x_crop_blocks, y_crop_blocks;
  371. int ci, i, j, offset_x, offset_y;
  372. JBLOCKARRAY src_buffer, dst_buffer;
  373. JCOEFPTR src_ptr, dst_ptr;
  374. jpeg_component_info *compptr;
  375. /* Because of the horizontal mirror step, we can't process partial iMCUs
  376. * at the (output) right edge properly. They just get transposed and
  377. * not mirrored.
  378. */
  379. MCU_cols = srcinfo->output_height /
  380. (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
  381. for (ci = 0; ci < dstinfo->num_components; ci++) {
  382. compptr = dstinfo->comp_info + ci;
  383. comp_width = MCU_cols * compptr->h_samp_factor;
  384. x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
  385. y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
  386. for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
  387. dst_blk_y += compptr->v_samp_factor) {
  388. dst_buffer = (*srcinfo->mem->access_virt_barray)
  389. ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
  390. (JDIMENSION)compptr->v_samp_factor, TRUE);
  391. for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
  392. for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
  393. dst_blk_x += compptr->h_samp_factor) {
  394. if (x_crop_blocks + dst_blk_x < comp_width) {
  395. /* Block is within the mirrorable area. */
  396. src_buffer = (*srcinfo->mem->access_virt_barray)
  397. ((j_common_ptr)srcinfo, src_coef_arrays[ci],
  398. comp_width - x_crop_blocks - dst_blk_x -
  399. (JDIMENSION)compptr->h_samp_factor,
  400. (JDIMENSION)compptr->h_samp_factor, FALSE);
  401. } else {
  402. /* Edge blocks are transposed but not mirrored. */
  403. src_buffer = (*srcinfo->mem->access_virt_barray)
  404. ((j_common_ptr)srcinfo, src_coef_arrays[ci],
  405. dst_blk_x + x_crop_blocks,
  406. (JDIMENSION)compptr->h_samp_factor, FALSE);
  407. }
  408. for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
  409. dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
  410. if (x_crop_blocks + dst_blk_x < comp_width) {
  411. /* Block is within the mirrorable area. */
  412. src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
  413. [dst_blk_y + offset_y + y_crop_blocks];
  414. for (i = 0; i < DCTSIZE; i++) {
  415. for (j = 0; j < DCTSIZE; j++)
  416. dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
  417. i++;
  418. for (j = 0; j < DCTSIZE; j++)
  419. dst_ptr[j * DCTSIZE + i] = -src_ptr[i * DCTSIZE + j];
  420. }
  421. } else {
  422. /* Edge blocks are transposed but not mirrored. */
  423. src_ptr = src_buffer[offset_x]
  424. [dst_blk_y + offset_y + y_crop_blocks];
  425. for (i = 0; i < DCTSIZE; i++)
  426. for (j = 0; j < DCTSIZE; j++)
  427. dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
  428. }
  429. }
  430. }
  431. }
  432. }
  433. }
  434. }
  435. LOCAL(void)
  436. do_rot_270(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
  437. JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
  438. jvirt_barray_ptr *src_coef_arrays,
  439. jvirt_barray_ptr *dst_coef_arrays)
  440. /* 270 degree rotation is equivalent to
  441. * 1. Horizontal mirroring;
  442. * 2. Transposing the image.
  443. * These two steps are merged into a single processing routine.
  444. */
  445. {
  446. JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
  447. JDIMENSION x_crop_blocks, y_crop_blocks;
  448. int ci, i, j, offset_x, offset_y;
  449. JBLOCKARRAY src_buffer, dst_buffer;
  450. JCOEFPTR src_ptr, dst_ptr;
  451. jpeg_component_info *compptr;
  452. /* Because of the horizontal mirror step, we can't process partial iMCUs
  453. * at the (output) bottom edge properly. They just get transposed and
  454. * not mirrored.
  455. */
  456. MCU_rows = srcinfo->output_width /
  457. (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
  458. for (ci = 0; ci < dstinfo->num_components; ci++) {
  459. compptr = dstinfo->comp_info + ci;
  460. comp_height = MCU_rows * compptr->v_samp_factor;
  461. x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
  462. y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
  463. for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
  464. dst_blk_y += compptr->v_samp_factor) {
  465. dst_buffer = (*srcinfo->mem->access_virt_barray)
  466. ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
  467. (JDIMENSION)compptr->v_samp_factor, TRUE);
  468. for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
  469. for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
  470. dst_blk_x += compptr->h_samp_factor) {
  471. src_buffer = (*srcinfo->mem->access_virt_barray)
  472. ((j_common_ptr)srcinfo, src_coef_arrays[ci],
  473. dst_blk_x + x_crop_blocks,
  474. (JDIMENSION)compptr->h_samp_factor, FALSE);
  475. for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
  476. dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
  477. if (y_crop_blocks + dst_blk_y < comp_height) {
  478. /* Block is within the mirrorable area. */
  479. src_ptr = src_buffer[offset_x]
  480. [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
  481. for (i = 0; i < DCTSIZE; i++) {
  482. for (j = 0; j < DCTSIZE; j++) {
  483. dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
  484. j++;
  485. dst_ptr[j * DCTSIZE + i] = -src_ptr[i * DCTSIZE + j];
  486. }
  487. }
  488. } else {
  489. /* Edge blocks are transposed but not mirrored. */
  490. src_ptr = src_buffer[offset_x]
  491. [dst_blk_y + offset_y + y_crop_blocks];
  492. for (i = 0; i < DCTSIZE; i++)
  493. for (j = 0; j < DCTSIZE; j++)
  494. dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
  495. }
  496. }
  497. }
  498. }
  499. }
  500. }
  501. }
  502. LOCAL(void)
  503. do_rot_180(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
  504. JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
  505. jvirt_barray_ptr *src_coef_arrays,
  506. jvirt_barray_ptr *dst_coef_arrays)
  507. /* 180 degree rotation is equivalent to
  508. * 1. Vertical mirroring;
  509. * 2. Horizontal mirroring.
  510. * These two steps are merged into a single processing routine.
  511. */
  512. {
  513. JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
  514. JDIMENSION x_crop_blocks, y_crop_blocks;
  515. int ci, i, j, offset_y;
  516. JBLOCKARRAY src_buffer, dst_buffer;
  517. JBLOCKROW src_row_ptr, dst_row_ptr;
  518. JCOEFPTR src_ptr, dst_ptr;
  519. jpeg_component_info *compptr;
  520. MCU_cols = srcinfo->output_width /
  521. (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
  522. MCU_rows = srcinfo->output_height /
  523. (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
  524. for (ci = 0; ci < dstinfo->num_components; ci++) {
  525. compptr = dstinfo->comp_info + ci;
  526. comp_width = MCU_cols * compptr->h_samp_factor;
  527. comp_height = MCU_rows * compptr->v_samp_factor;
  528. x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
  529. y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
  530. for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
  531. dst_blk_y += compptr->v_samp_factor) {
  532. dst_buffer = (*srcinfo->mem->access_virt_barray)
  533. ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
  534. (JDIMENSION)compptr->v_samp_factor, TRUE);
  535. if (y_crop_blocks + dst_blk_y < comp_height) {
  536. /* Row is within the vertically mirrorable area. */
  537. src_buffer = (*srcinfo->mem->access_virt_barray)
  538. ((j_common_ptr)srcinfo, src_coef_arrays[ci],
  539. comp_height - y_crop_blocks - dst_blk_y -
  540. (JDIMENSION)compptr->v_samp_factor,
  541. (JDIMENSION)compptr->v_samp_factor, FALSE);
  542. } else {
  543. /* Bottom-edge rows are only mirrored horizontally. */
  544. src_buffer = (*srcinfo->mem->access_virt_barray)
  545. ((j_common_ptr)srcinfo, src_coef_arrays[ci],
  546. dst_blk_y + y_crop_blocks,
  547. (JDIMENSION)compptr->v_samp_factor, FALSE);
  548. }
  549. for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
  550. dst_row_ptr = dst_buffer[offset_y];
  551. if (y_crop_blocks + dst_blk_y < comp_height) {
  552. /* Row is within the mirrorable area. */
  553. src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
  554. for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
  555. dst_blk_x++) {
  556. dst_ptr = dst_row_ptr[dst_blk_x];
  557. if (x_crop_blocks + dst_blk_x < comp_width) {
  558. /* Process the blocks that can be mirrored both ways. */
  559. src_ptr =
  560. src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
  561. for (i = 0; i < DCTSIZE; i += 2) {
  562. /* For even row, negate every odd column. */
  563. for (j = 0; j < DCTSIZE; j += 2) {
  564. *dst_ptr++ = *src_ptr++;
  565. *dst_ptr++ = - *src_ptr++;
  566. }
  567. /* For odd row, negate every even column. */
  568. for (j = 0; j < DCTSIZE; j += 2) {
  569. *dst_ptr++ = - *src_ptr++;
  570. *dst_ptr++ = *src_ptr++;
  571. }
  572. }
  573. } else {
  574. /* Any remaining right-edge blocks are only mirrored vertically. */
  575. src_ptr = src_row_ptr[x_crop_blocks + dst_blk_x];
  576. for (i = 0; i < DCTSIZE; i += 2) {
  577. for (j = 0; j < DCTSIZE; j++)
  578. *dst_ptr++ = *src_ptr++;
  579. for (j = 0; j < DCTSIZE; j++)
  580. *dst_ptr++ = - *src_ptr++;
  581. }
  582. }
  583. }
  584. } else {
  585. /* Remaining rows are just mirrored horizontally. */
  586. src_row_ptr = src_buffer[offset_y];
  587. for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
  588. dst_blk_x++) {
  589. if (x_crop_blocks + dst_blk_x < comp_width) {
  590. /* Process the blocks that can be mirrored. */
  591. dst_ptr = dst_row_ptr[dst_blk_x];
  592. src_ptr =
  593. src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
  594. for (i = 0; i < DCTSIZE2; i += 2) {
  595. *dst_ptr++ = *src_ptr++;
  596. *dst_ptr++ = - *src_ptr++;
  597. }
  598. } else {
  599. /* Any remaining right-edge blocks are only copied. */
  600. jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
  601. dst_row_ptr + dst_blk_x, (JDIMENSION)1);
  602. }
  603. }
  604. }
  605. }
  606. }
  607. }
  608. }
  609. LOCAL(void)
  610. do_transverse(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
  611. JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
  612. jvirt_barray_ptr *src_coef_arrays,
  613. jvirt_barray_ptr *dst_coef_arrays)
  614. /* Transverse transpose is equivalent to
  615. * 1. 180 degree rotation;
  616. * 2. Transposition;
  617. * or
  618. * 1. Horizontal mirroring;
  619. * 2. Transposition;
  620. * 3. Horizontal mirroring.
  621. * These steps are merged into a single processing routine.
  622. */
  623. {
  624. JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
  625. JDIMENSION x_crop_blocks, y_crop_blocks;
  626. int ci, i, j, offset_x, offset_y;
  627. JBLOCKARRAY src_buffer, dst_buffer;
  628. JCOEFPTR src_ptr, dst_ptr;
  629. jpeg_component_info *compptr;
  630. MCU_cols = srcinfo->output_height /
  631. (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
  632. MCU_rows = srcinfo->output_width /
  633. (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
  634. for (ci = 0; ci < dstinfo->num_components; ci++) {
  635. compptr = dstinfo->comp_info + ci;
  636. comp_width = MCU_cols * compptr->h_samp_factor;
  637. comp_height = MCU_rows * compptr->v_samp_factor;
  638. x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
  639. y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
  640. for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
  641. dst_blk_y += compptr->v_samp_factor) {
  642. dst_buffer = (*srcinfo->mem->access_virt_barray)
  643. ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
  644. (JDIMENSION)compptr->v_samp_factor, TRUE);
  645. for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
  646. for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
  647. dst_blk_x += compptr->h_samp_factor) {
  648. if (x_crop_blocks + dst_blk_x < comp_width) {
  649. /* Block is within the mirrorable area. */
  650. src_buffer = (*srcinfo->mem->access_virt_barray)
  651. ((j_common_ptr)srcinfo, src_coef_arrays[ci],
  652. comp_width - x_crop_blocks - dst_blk_x -
  653. (JDIMENSION)compptr->h_samp_factor,
  654. (JDIMENSION)compptr->h_samp_factor, FALSE);
  655. } else {
  656. src_buffer = (*srcinfo->mem->access_virt_barray)
  657. ((j_common_ptr)srcinfo, src_coef_arrays[ci],
  658. dst_blk_x + x_crop_blocks,
  659. (JDIMENSION)compptr->h_samp_factor, FALSE);
  660. }
  661. for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
  662. dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
  663. if (y_crop_blocks + dst_blk_y < comp_height) {
  664. if (x_crop_blocks + dst_blk_x < comp_width) {
  665. /* Block is within the mirrorable area. */
  666. src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
  667. [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
  668. for (i = 0; i < DCTSIZE; i++) {
  669. for (j = 0; j < DCTSIZE; j++) {
  670. dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
  671. j++;
  672. dst_ptr[j * DCTSIZE + i] = -src_ptr[i * DCTSIZE + j];
  673. }
  674. i++;
  675. for (j = 0; j < DCTSIZE; j++) {
  676. dst_ptr[j * DCTSIZE + i] = -src_ptr[i * DCTSIZE + j];
  677. j++;
  678. dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
  679. }
  680. }
  681. } else {
  682. /* Right-edge blocks are mirrored in y only */
  683. src_ptr = src_buffer[offset_x]
  684. [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
  685. for (i = 0; i < DCTSIZE; i++) {
  686. for (j = 0; j < DCTSIZE; j++) {
  687. dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
  688. j++;
  689. dst_ptr[j * DCTSIZE + i] = -src_ptr[i * DCTSIZE + j];
  690. }
  691. }
  692. }
  693. } else {
  694. if (x_crop_blocks + dst_blk_x < comp_width) {
  695. /* Bottom-edge blocks are mirrored in x only */
  696. src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
  697. [dst_blk_y + offset_y + y_crop_blocks];
  698. for (i = 0; i < DCTSIZE; i++) {
  699. for (j = 0; j < DCTSIZE; j++)
  700. dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
  701. i++;
  702. for (j = 0; j < DCTSIZE; j++)
  703. dst_ptr[j * DCTSIZE + i] = -src_ptr[i * DCTSIZE + j];
  704. }
  705. } else {
  706. /* At lower right corner, just transpose, no mirroring */
  707. src_ptr = src_buffer[offset_x]
  708. [dst_blk_y + offset_y + y_crop_blocks];
  709. for (i = 0; i < DCTSIZE; i++)
  710. for (j = 0; j < DCTSIZE; j++)
  711. dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
  712. }
  713. }
  714. }
  715. }
  716. }
  717. }
  718. }
  719. }
  720. /* Parse an unsigned integer: subroutine for jtransform_parse_crop_spec.
  721. * Returns TRUE if valid integer found, FALSE if not.
  722. * *strptr is advanced over the digit string, and *result is set to its value.
  723. */
  724. LOCAL(boolean)
  725. jt_read_integer(const char **strptr, JDIMENSION *result)
  726. {
  727. const char *ptr = *strptr;
  728. JDIMENSION val = 0;
  729. for (; isdigit(*ptr); ptr++) {
  730. val = val * 10 + (JDIMENSION)(*ptr - '0');
  731. }
  732. *result = val;
  733. if (ptr == *strptr)
  734. return FALSE; /* oops, no digits */
  735. *strptr = ptr;
  736. return TRUE;
  737. }
  738. /* Parse a crop specification (written in X11 geometry style).
  739. * The routine returns TRUE if the spec string is valid, FALSE if not.
  740. *
  741. * The crop spec string should have the format
  742. * <width>[f]x<height>[f]{+-}<xoffset>{+-}<yoffset>
  743. * where width, height, xoffset, and yoffset are unsigned integers.
  744. * Each of the elements can be omitted to indicate a default value.
  745. * (A weakness of this style is that it is not possible to omit xoffset
  746. * while specifying yoffset, since they look alike.)
  747. *
  748. * This code is loosely based on XParseGeometry from the X11 distribution.
  749. */
  750. GLOBAL(boolean)
  751. jtransform_parse_crop_spec(jpeg_transform_info *info, const char *spec)
  752. {
  753. info->crop = FALSE;
  754. info->crop_width_set = JCROP_UNSET;
  755. info->crop_height_set = JCROP_UNSET;
  756. info->crop_xoffset_set = JCROP_UNSET;
  757. info->crop_yoffset_set = JCROP_UNSET;
  758. if (isdigit(*spec)) {
  759. /* fetch width */
  760. if (!jt_read_integer(&spec, &info->crop_width))
  761. return FALSE;
  762. if (*spec == 'f' || *spec == 'F') {
  763. spec++;
  764. info->crop_width_set = JCROP_FORCE;
  765. } else
  766. info->crop_width_set = JCROP_POS;
  767. }
  768. if (*spec == 'x' || *spec == 'X') {
  769. /* fetch height */
  770. spec++;
  771. if (!jt_read_integer(&spec, &info->crop_height))
  772. return FALSE;
  773. if (*spec == 'f' || *spec == 'F') {
  774. spec++;
  775. info->crop_height_set = JCROP_FORCE;
  776. } else
  777. info->crop_height_set = JCROP_POS;
  778. }
  779. if (*spec == '+' || *spec == '-') {
  780. /* fetch xoffset */
  781. info->crop_xoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS;
  782. spec++;
  783. if (!jt_read_integer(&spec, &info->crop_xoffset))
  784. return FALSE;
  785. }
  786. if (*spec == '+' || *spec == '-') {
  787. /* fetch yoffset */
  788. info->crop_yoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS;
  789. spec++;
  790. if (!jt_read_integer(&spec, &info->crop_yoffset))
  791. return FALSE;
  792. }
  793. /* We had better have gotten to the end of the string. */
  794. if (*spec != '\0')
  795. return FALSE;
  796. info->crop = TRUE;
  797. return TRUE;
  798. }
  799. /* Trim off any partial iMCUs on the indicated destination edge */
  800. LOCAL(void)
  801. trim_right_edge(jpeg_transform_info *info, JDIMENSION full_width)
  802. {
  803. JDIMENSION MCU_cols;
  804. MCU_cols = info->output_width / info->iMCU_sample_width;
  805. if (MCU_cols > 0 && info->x_crop_offset + MCU_cols ==
  806. full_width / info->iMCU_sample_width)
  807. info->output_width = MCU_cols * info->iMCU_sample_width;
  808. }
  809. LOCAL(void)
  810. trim_bottom_edge(jpeg_transform_info *info, JDIMENSION full_height)
  811. {
  812. JDIMENSION MCU_rows;
  813. MCU_rows = info->output_height / info->iMCU_sample_height;
  814. if (MCU_rows > 0 && info->y_crop_offset + MCU_rows ==
  815. full_height / info->iMCU_sample_height)
  816. info->output_height = MCU_rows * info->iMCU_sample_height;
  817. }
  818. /* Request any required workspace.
  819. *
  820. * This routine figures out the size that the output image will be
  821. * (which implies that all the transform parameters must be set before
  822. * it is called).
  823. *
  824. * We allocate the workspace virtual arrays from the source decompression
  825. * object, so that all the arrays (both the original data and the workspace)
  826. * will be taken into account while making memory management decisions.
  827. * Hence, this routine must be called after jpeg_read_header (which reads
  828. * the image dimensions) and before jpeg_read_coefficients (which realizes
  829. * the source's virtual arrays).
  830. *
  831. * This function returns FALSE right away if -perfect is given
  832. * and transformation is not perfect. Otherwise returns TRUE.
  833. */
  834. GLOBAL(boolean)
  835. jtransform_request_workspace(j_decompress_ptr srcinfo,
  836. jpeg_transform_info *info)
  837. {
  838. jvirt_barray_ptr *coef_arrays;
  839. boolean need_workspace, transpose_it;
  840. jpeg_component_info *compptr;
  841. JDIMENSION xoffset, yoffset;
  842. JDIMENSION width_in_iMCUs, height_in_iMCUs;
  843. JDIMENSION width_in_blocks, height_in_blocks;
  844. int ci, h_samp_factor, v_samp_factor;
  845. /* Determine number of components in output image */
  846. if (info->force_grayscale &&
  847. srcinfo->jpeg_color_space == JCS_YCbCr &&
  848. srcinfo->num_components == 3)
  849. /* We'll only process the first component */
  850. info->num_components = 1;
  851. else
  852. /* Process all the components */
  853. info->num_components = srcinfo->num_components;
  854. /* Compute output image dimensions and related values. */
  855. #if JPEG_LIB_VERSION >= 80
  856. jpeg_core_output_dimensions(srcinfo);
  857. #else
  858. srcinfo->output_width = srcinfo->image_width;
  859. srcinfo->output_height = srcinfo->image_height;
  860. #endif
  861. /* Return right away if -perfect is given and transformation is not perfect.
  862. */
  863. if (info->perfect) {
  864. if (info->num_components == 1) {
  865. if (!jtransform_perfect_transform(srcinfo->output_width,
  866. srcinfo->output_height,
  867. srcinfo->_min_DCT_h_scaled_size,
  868. srcinfo->_min_DCT_v_scaled_size,
  869. info->transform))
  870. return FALSE;
  871. } else {
  872. if (!jtransform_perfect_transform(srcinfo->output_width,
  873. srcinfo->output_height,
  874. srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size,
  875. srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size,
  876. info->transform))
  877. return FALSE;
  878. }
  879. }
  880. /* If there is only one output component, force the iMCU size to be 1;
  881. * else use the source iMCU size. (This allows us to do the right thing
  882. * when reducing color to grayscale, and also provides a handy way of
  883. * cleaning up "funny" grayscale images whose sampling factors are not 1x1.)
  884. */
  885. switch (info->transform) {
  886. case JXFORM_TRANSPOSE:
  887. case JXFORM_TRANSVERSE:
  888. case JXFORM_ROT_90:
  889. case JXFORM_ROT_270:
  890. info->output_width = srcinfo->output_height;
  891. info->output_height = srcinfo->output_width;
  892. if (info->num_components == 1) {
  893. info->iMCU_sample_width = srcinfo->_min_DCT_v_scaled_size;
  894. info->iMCU_sample_height = srcinfo->_min_DCT_h_scaled_size;
  895. } else {
  896. info->iMCU_sample_width =
  897. srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size;
  898. info->iMCU_sample_height =
  899. srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size;
  900. }
  901. break;
  902. default:
  903. info->output_width = srcinfo->output_width;
  904. info->output_height = srcinfo->output_height;
  905. if (info->num_components == 1) {
  906. info->iMCU_sample_width = srcinfo->_min_DCT_h_scaled_size;
  907. info->iMCU_sample_height = srcinfo->_min_DCT_v_scaled_size;
  908. } else {
  909. info->iMCU_sample_width =
  910. srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size;
  911. info->iMCU_sample_height =
  912. srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size;
  913. }
  914. break;
  915. }
  916. /* If cropping has been requested, compute the crop area's position and
  917. * dimensions, ensuring that its upper left corner falls at an iMCU boundary.
  918. */
  919. if (info->crop) {
  920. /* Insert default values for unset crop parameters */
  921. if (info->crop_xoffset_set == JCROP_UNSET)
  922. info->crop_xoffset = 0; /* default to +0 */
  923. if (info->crop_yoffset_set == JCROP_UNSET)
  924. info->crop_yoffset = 0; /* default to +0 */
  925. if (info->crop_xoffset >= info->output_width ||
  926. info->crop_yoffset >= info->output_height)
  927. ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
  928. if (info->crop_width_set == JCROP_UNSET)
  929. info->crop_width = info->output_width - info->crop_xoffset;
  930. if (info->crop_height_set == JCROP_UNSET)
  931. info->crop_height = info->output_height - info->crop_yoffset;
  932. /* Ensure parameters are valid */
  933. if (info->crop_width <= 0 || info->crop_width > info->output_width ||
  934. info->crop_height <= 0 || info->crop_height > info->output_height ||
  935. info->crop_xoffset > info->output_width - info->crop_width ||
  936. info->crop_yoffset > info->output_height - info->crop_height)
  937. ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
  938. /* Convert negative crop offsets into regular offsets */
  939. if (info->crop_xoffset_set == JCROP_NEG)
  940. xoffset = info->output_width - info->crop_width - info->crop_xoffset;
  941. else
  942. xoffset = info->crop_xoffset;
  943. if (info->crop_yoffset_set == JCROP_NEG)
  944. yoffset = info->output_height - info->crop_height - info->crop_yoffset;
  945. else
  946. yoffset = info->crop_yoffset;
  947. /* Now adjust so that upper left corner falls at an iMCU boundary */
  948. if (info->crop_width_set == JCROP_FORCE)
  949. info->output_width = info->crop_width;
  950. else
  951. info->output_width =
  952. info->crop_width + (xoffset % info->iMCU_sample_width);
  953. if (info->crop_height_set == JCROP_FORCE)
  954. info->output_height = info->crop_height;
  955. else
  956. info->output_height =
  957. info->crop_height + (yoffset % info->iMCU_sample_height);
  958. /* Save x/y offsets measured in iMCUs */
  959. info->x_crop_offset = xoffset / info->iMCU_sample_width;
  960. info->y_crop_offset = yoffset / info->iMCU_sample_height;
  961. } else {
  962. info->x_crop_offset = 0;
  963. info->y_crop_offset = 0;
  964. }
  965. /* Figure out whether we need workspace arrays,
  966. * and if so whether they are transposed relative to the source.
  967. */
  968. need_workspace = FALSE;
  969. transpose_it = FALSE;
  970. switch (info->transform) {
  971. case JXFORM_NONE:
  972. if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
  973. need_workspace = TRUE;
  974. /* No workspace needed if neither cropping nor transforming */
  975. break;
  976. case JXFORM_FLIP_H:
  977. if (info->trim)
  978. trim_right_edge(info, srcinfo->output_width);
  979. if (info->y_crop_offset != 0 || info->slow_hflip)
  980. need_workspace = TRUE;
  981. /* do_flip_h_no_crop doesn't need a workspace array */
  982. break;
  983. case JXFORM_FLIP_V:
  984. if (info->trim)
  985. trim_bottom_edge(info, srcinfo->output_height);
  986. /* Need workspace arrays having same dimensions as source image. */
  987. need_workspace = TRUE;
  988. break;
  989. case JXFORM_TRANSPOSE:
  990. /* transpose does NOT have to trim anything */
  991. /* Need workspace arrays having transposed dimensions. */
  992. need_workspace = TRUE;
  993. transpose_it = TRUE;
  994. break;
  995. case JXFORM_TRANSVERSE:
  996. if (info->trim) {
  997. trim_right_edge(info, srcinfo->output_height);
  998. trim_bottom_edge(info, srcinfo->output_width);
  999. }
  1000. /* Need workspace arrays having transposed dimensions. */
  1001. need_workspace = TRUE;
  1002. transpose_it = TRUE;
  1003. break;
  1004. case JXFORM_ROT_90:
  1005. if (info->trim)
  1006. trim_right_edge(info, srcinfo->output_height);
  1007. /* Need workspace arrays having transposed dimensions. */
  1008. need_workspace = TRUE;
  1009. transpose_it = TRUE;
  1010. break;
  1011. case JXFORM_ROT_180:
  1012. if (info->trim) {
  1013. trim_right_edge(info, srcinfo->output_width);
  1014. trim_bottom_edge(info, srcinfo->output_height);
  1015. }
  1016. /* Need workspace arrays having same dimensions as source image. */
  1017. need_workspace = TRUE;
  1018. break;
  1019. case JXFORM_ROT_270:
  1020. if (info->trim)
  1021. trim_bottom_edge(info, srcinfo->output_width);
  1022. /* Need workspace arrays having transposed dimensions. */
  1023. need_workspace = TRUE;
  1024. transpose_it = TRUE;
  1025. break;
  1026. }
  1027. /* Allocate workspace if needed.
  1028. * Note that we allocate arrays padded out to the next iMCU boundary,
  1029. * so that transform routines need not worry about missing edge blocks.
  1030. */
  1031. if (need_workspace) {
  1032. coef_arrays = (jvirt_barray_ptr *)
  1033. (*srcinfo->mem->alloc_small) ((j_common_ptr)srcinfo, JPOOL_IMAGE,
  1034. sizeof(jvirt_barray_ptr) * info->num_components);
  1035. width_in_iMCUs = (JDIMENSION)
  1036. jdiv_round_up((long)info->output_width, (long)info->iMCU_sample_width);
  1037. height_in_iMCUs = (JDIMENSION)
  1038. jdiv_round_up((long)info->output_height, (long)info->iMCU_sample_height);
  1039. for (ci = 0; ci < info->num_components; ci++) {
  1040. compptr = srcinfo->comp_info + ci;
  1041. if (info->num_components == 1) {
  1042. /* we're going to force samp factors to 1x1 in this case */
  1043. h_samp_factor = v_samp_factor = 1;
  1044. } else if (transpose_it) {
  1045. h_samp_factor = compptr->v_samp_factor;
  1046. v_samp_factor = compptr->h_samp_factor;
  1047. } else {
  1048. h_samp_factor = compptr->h_samp_factor;
  1049. v_samp_factor = compptr->v_samp_factor;
  1050. }
  1051. width_in_blocks = width_in_iMCUs * h_samp_factor;
  1052. height_in_blocks = height_in_iMCUs * v_samp_factor;
  1053. coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
  1054. ((j_common_ptr)srcinfo, JPOOL_IMAGE, FALSE,
  1055. width_in_blocks, height_in_blocks, (JDIMENSION)v_samp_factor);
  1056. }
  1057. info->workspace_coef_arrays = coef_arrays;
  1058. } else
  1059. info->workspace_coef_arrays = NULL;
  1060. return TRUE;
  1061. }
  1062. /* Transpose destination image parameters */
  1063. LOCAL(void)
  1064. transpose_critical_parameters(j_compress_ptr dstinfo)
  1065. {
  1066. int tblno, i, j, ci, itemp;
  1067. jpeg_component_info *compptr;
  1068. JQUANT_TBL *qtblptr;
  1069. JDIMENSION jtemp;
  1070. UINT16 qtemp;
  1071. /* Transpose image dimensions */
  1072. jtemp = dstinfo->image_width;
  1073. dstinfo->image_width = dstinfo->image_height;
  1074. dstinfo->image_height = jtemp;
  1075. #if JPEG_LIB_VERSION >= 70
  1076. itemp = dstinfo->min_DCT_h_scaled_size;
  1077. dstinfo->min_DCT_h_scaled_size = dstinfo->min_DCT_v_scaled_size;
  1078. dstinfo->min_DCT_v_scaled_size = itemp;
  1079. #endif
  1080. /* Transpose sampling factors */
  1081. for (ci = 0; ci < dstinfo->num_components; ci++) {
  1082. compptr = dstinfo->comp_info + ci;
  1083. itemp = compptr->h_samp_factor;
  1084. compptr->h_samp_factor = compptr->v_samp_factor;
  1085. compptr->v_samp_factor = itemp;
  1086. }
  1087. /* Transpose quantization tables */
  1088. for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
  1089. qtblptr = dstinfo->quant_tbl_ptrs[tblno];
  1090. if (qtblptr != NULL) {
  1091. for (i = 0; i < DCTSIZE; i++) {
  1092. for (j = 0; j < i; j++) {
  1093. qtemp = qtblptr->quantval[i * DCTSIZE + j];
  1094. qtblptr->quantval[i * DCTSIZE + j] =
  1095. qtblptr->quantval[j * DCTSIZE + i];
  1096. qtblptr->quantval[j * DCTSIZE + i] = qtemp;
  1097. }
  1098. }
  1099. }
  1100. }
  1101. }
  1102. /* Adjust Exif image parameters.
  1103. *
  1104. * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible.
  1105. */
  1106. LOCAL(void)
  1107. adjust_exif_parameters(JOCTET *data, unsigned int length, JDIMENSION new_width,
  1108. JDIMENSION new_height)
  1109. {
  1110. boolean is_motorola; /* Flag for byte order */
  1111. unsigned int number_of_tags, tagnum;
  1112. unsigned int firstoffset, offset;
  1113. JDIMENSION new_value;
  1114. if (length < 12) return; /* Length of an IFD entry */
  1115. /* Discover byte order */
  1116. if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49)
  1117. is_motorola = FALSE;
  1118. else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D)
  1119. is_motorola = TRUE;
  1120. else
  1121. return;
  1122. /* Check Tag Mark */
  1123. if (is_motorola) {
  1124. if (GETJOCTET(data[2]) != 0) return;
  1125. if (GETJOCTET(data[3]) != 0x2A) return;
  1126. } else {
  1127. if (GETJOCTET(data[3]) != 0) return;
  1128. if (GETJOCTET(data[2]) != 0x2A) return;
  1129. }
  1130. /* Get first IFD offset (offset to IFD0) */
  1131. if (is_motorola) {
  1132. if (GETJOCTET(data[4]) != 0) return;
  1133. if (GETJOCTET(data[5]) != 0) return;
  1134. firstoffset = GETJOCTET(data[6]);
  1135. firstoffset <<= 8;
  1136. firstoffset += GETJOCTET(data[7]);
  1137. } else {
  1138. if (GETJOCTET(data[7]) != 0) return;
  1139. if (GETJOCTET(data[6]) != 0) return;
  1140. firstoffset = GETJOCTET(data[5]);
  1141. firstoffset <<= 8;
  1142. firstoffset += GETJOCTET(data[4]);
  1143. }
  1144. if (firstoffset > length - 2) return; /* check end of data segment */
  1145. /* Get the number of directory entries contained in this IFD */
  1146. if (is_motorola) {
  1147. number_of_tags = GETJOCTET(data[firstoffset]);
  1148. number_of_tags <<= 8;
  1149. number_of_tags += GETJOCTET(data[firstoffset + 1]);
  1150. } else {
  1151. number_of_tags = GETJOCTET(data[firstoffset + 1]);
  1152. number_of_tags <<= 8;
  1153. number_of_tags += GETJOCTET(data[firstoffset]);
  1154. }
  1155. if (number_of_tags == 0) return;
  1156. firstoffset += 2;
  1157. /* Search for ExifSubIFD offset Tag in IFD0 */
  1158. for (;;) {
  1159. if (firstoffset > length - 12) return; /* check end of data segment */
  1160. /* Get Tag number */
  1161. if (is_motorola) {
  1162. tagnum = GETJOCTET(data[firstoffset]);
  1163. tagnum <<= 8;
  1164. tagnum += GETJOCTET(data[firstoffset + 1]);
  1165. } else {
  1166. tagnum = GETJOCTET(data[firstoffset + 1]);
  1167. tagnum <<= 8;
  1168. tagnum += GETJOCTET(data[firstoffset]);
  1169. }
  1170. if (tagnum == 0x8769) break; /* found ExifSubIFD offset Tag */
  1171. if (--number_of_tags == 0) return;
  1172. firstoffset += 12;
  1173. }
  1174. /* Get the ExifSubIFD offset */
  1175. if (is_motorola) {
  1176. if (GETJOCTET(data[firstoffset + 8]) != 0) return;
  1177. if (GETJOCTET(data[firstoffset + 9]) != 0) return;
  1178. offset = GETJOCTET(data[firstoffset + 10]);
  1179. offset <<= 8;
  1180. offset += GETJOCTET(data[firstoffset + 11]);
  1181. } else {
  1182. if (GETJOCTET(data[firstoffset + 11]) != 0) return;
  1183. if (GETJOCTET(data[firstoffset + 10]) != 0) return;
  1184. offset = GETJOCTET(data[firstoffset + 9]);
  1185. offset <<= 8;
  1186. offset += GETJOCTET(data[firstoffset + 8]);
  1187. }
  1188. if (offset > length - 2) return; /* check end of data segment */
  1189. /* Get the number of directory entries contained in this SubIFD */
  1190. if (is_motorola) {
  1191. number_of_tags = GETJOCTET(data[offset]);
  1192. number_of_tags <<= 8;
  1193. number_of_tags += GETJOCTET(data[offset + 1]);
  1194. } else {
  1195. number_of_tags = GETJOCTET(data[offset + 1]);
  1196. number_of_ta

Large files files are truncated, but you can click here to view the full file