transupp.c 62 KB

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