transupp.c 54 KB

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