transupp.c 61 KB

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