PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/src/third_party/OpenExif/src/ExifIJGWriteFrame.cpp

https://github.com/Divo2011/libmv
C++ | 288 lines | 164 code | 52 blank | 72 comment | 43 complexity | 6952d3c7870aaba16ec323e67294cb2a MD5 | raw file
  1. /*
  2. * Copyright (c) 2000-2009, Eastman Kodak Company
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification,are permitted provided that the following conditions are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * * Neither the name of the Eastman Kodak Company nor the names of its
  14. * contributors may be used to endorse or promote products derived from
  15. * this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  18. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  21. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  22. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  24. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  25. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  26. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  27. * POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. * Creation Date: 12/04/2004
  30. *
  31. * Original Author:
  32. * Sam Fryer samuel.fryer@kodak.com
  33. *
  34. * Contributor(s):
  35. *
  36. *
  37. * Portions of this code were taken from the IJG jpeg toolkit version 6b
  38. * from the file "jcmarker.c" which had the copyright notice
  39. * reproduced below.
  40. */
  41. /*
  42. * jcmarker.c
  43. *
  44. * Copyright (C) 1991-1998, Thomas G. Lane.
  45. * This file is part of the Independent JPEG Group's software.
  46. * For conditions of distribution and use, see the accompanying README file.
  47. *
  48. * This file contains routines to write JPEG datastream markers.
  49. */
  50. #include "ExifComp.h"
  51. #ifdef OPENEXIF_DCF_COMPLIANT
  52. #ifndef OPENEXIF_NO_IJG
  53. #define JPEG_INTERNALS
  54. #include "OpenExif_jinclude.h"
  55. #include "OpenExifJpegLib.h"
  56. #define M_DQT 0xDB
  57. #define M_DHT 0xC4
  58. void openexif_ijg_emit_byte (j_compress_ptr cinfo, int val)
  59. /* Emit a byte */
  60. {
  61. struct openexif_jpeg_destination_mgr * dest = cinfo->dest;
  62. *(dest->next_output_byte)++ = (JOCTET) val;
  63. if (--dest->free_in_buffer == 0) {
  64. if (! (*dest->empty_output_buffer) (cinfo))
  65. ERREXIT(cinfo, JERR_CANT_SUSPEND);
  66. }
  67. }
  68. void openexif_ijg_emit_2bytes (j_compress_ptr cinfo, int value)
  69. /* Emit a 2-byte integer; these are always MSB first in JPEG files */
  70. {
  71. openexif_ijg_emit_byte(cinfo, (value >> 8) & 0xFF);
  72. openexif_ijg_emit_byte(cinfo, value & 0xFF);
  73. }
  74. void (*openexif_orig_write_frame_header) (j_compress_ptr cinfo);
  75. void openexif_write_frame_header (j_compress_ptr cinfo)
  76. {
  77. int ci;
  78. openexif_jpeg_component_info *compptr;
  79. int prec[MAX_COMPONENTS];
  80. int index=0;
  81. JQUANT_TBL * qtbl = NULL;
  82. JQUANT_TBL * qtblList[MAX_COMPONENTS];
  83. int i=0;
  84. int length = 2;
  85. memset(qtblList,0,MAX_COMPONENTS*sizeof(JQUANT_TBL *));
  86. for (ci = 0, compptr = cinfo->comp_info;
  87. ci < cinfo->num_components;
  88. ci++, compptr++)
  89. {
  90. index = compptr->quant_tbl_no;
  91. qtbl = cinfo->quant_tbl_ptrs[index];
  92. if (qtbl == NULL)
  93. ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);
  94. i=0;
  95. while(( qtblList[i] != NULL ) && ( qtblList[i] != qtbl ))
  96. i++;
  97. if ( qtblList[i] == NULL )
  98. {
  99. qtblList[i] = qtbl;
  100. prec[index] = 0;
  101. for (i = 0; i < DCTSIZE2; i++)
  102. {
  103. if (qtbl->quantval[i] > 255)
  104. prec[index] = 1;
  105. }
  106. length += 1 + DCTSIZE2 + DCTSIZE2*prec[index];
  107. }
  108. }
  109. /* emit the DQT marker */
  110. openexif_ijg_emit_byte(cinfo, 0xFF);
  111. openexif_ijg_emit_byte(cinfo, M_DQT);
  112. openexif_ijg_emit_2bytes(cinfo, length);
  113. for (ci = 0, compptr = cinfo->comp_info;
  114. ci < cinfo->num_components;
  115. ci++, compptr++)
  116. {
  117. index = compptr->quant_tbl_no;
  118. qtbl = cinfo->quant_tbl_ptrs[index];
  119. if (! qtbl->sent_table)
  120. {
  121. openexif_ijg_emit_byte(cinfo, index + (prec[index]<<4));
  122. for (i = 0; i < DCTSIZE2; i++)
  123. {
  124. /* The table entries must be emitted in zigzag order. */
  125. unsigned int qval = qtbl->quantval[openexif_jpeg_natural_order[i]];
  126. if (prec[index])
  127. openexif_ijg_emit_byte(cinfo, (int) (qval >> 8));
  128. openexif_ijg_emit_byte(cinfo, (int) (qval & 0xFF));
  129. }
  130. qtbl->sent_table = TRUE;
  131. }
  132. }
  133. /* Now call the original to post the rest of the frame ... */
  134. (*openexif_orig_write_frame_header)(cinfo);
  135. }
  136. int compute_dht_length(JHUFF_TBL * htbl)
  137. {
  138. int length, i;
  139. length = 17;
  140. for (i = 1; i <= 16; i++)
  141. length += htbl->bits[i];
  142. return length;
  143. }
  144. void compute_htblList(JHUFF_TBL * htbl,JHUFF_TBL * htblList[],
  145. int i, int index[])
  146. {
  147. if (! htbl->sent_table)
  148. {
  149. int k=0;
  150. while(( htblList[k] != NULL ) && ( htblList[k] != htbl ))
  151. k++;
  152. if (( htblList[k] == NULL ) && ( htbl != NULL ) && (! htbl->sent_table))
  153. {
  154. htblList[k] = htbl;
  155. index[k] = i;
  156. }
  157. }
  158. }
  159. void (*openexif_orig_write_scan_header) (j_compress_ptr cinfo);
  160. void openexif_write_scan_header (j_compress_ptr cinfo)
  161. {
  162. int i,j,k,c;
  163. openexif_jpeg_component_info *compptr;
  164. int length = 2;
  165. JHUFF_TBL * htblList[MAX_COMPONENTS];
  166. int index[MAX_COMPONENTS];
  167. if (!cinfo->arith_code)
  168. {
  169. memset(htblList,0,MAX_COMPONENTS*sizeof(JHUFF_TBL *));
  170. /* Emit Huffman tables.
  171. * Note that emit_dht() suppresses any duplicate tables.
  172. */
  173. /*
  174. * First, get the tables involved, without duplication....
  175. */
  176. for (i = 0; i < cinfo->comps_in_scan; i++)
  177. {
  178. JHUFF_TBL * htbl = NULL;
  179. compptr = cinfo->cur_comp_info[i];
  180. if (cinfo->progressive_mode)
  181. {
  182. /* Progressive mode: only DC or only AC tables are used in one scan */
  183. if (cinfo->Ss == 0) {
  184. if (cinfo->Ah == 0) /* DC needs no table for refinement scan */
  185. htbl = cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no];
  186. compute_htblList(htbl,htblList,compptr->dc_tbl_no,index);
  187. } else {
  188. htbl = cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no];
  189. compute_htblList(htbl,htblList,compptr->ac_tbl_no | 0x10,index);
  190. }
  191. } else {
  192. /* Sequential mode: need both DC and AC tables */
  193. htbl = cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no];
  194. compute_htblList(htbl,htblList,compptr->dc_tbl_no,index);
  195. htbl = cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no];
  196. compute_htblList(htbl,htblList,compptr->ac_tbl_no | 0x10,index);
  197. }
  198. }
  199. /*
  200. * Second, compute the total length....
  201. */
  202. i=0;
  203. while (htblList[i] != NULL)
  204. {
  205. length += compute_dht_length(htblList[i]);
  206. i++;
  207. }
  208. /*
  209. * Third, write out the marker and length ...
  210. */
  211. openexif_ijg_emit_byte(cinfo, 0xFF);
  212. openexif_ijg_emit_byte(cinfo, M_DHT);
  213. openexif_ijg_emit_2bytes(cinfo, length);
  214. /*
  215. * Then, write the tables out....
  216. */
  217. i=0;
  218. while (htblList[i] != NULL)
  219. {
  220. JHUFF_TBL * htbl = htblList[i];
  221. openexif_ijg_emit_byte(cinfo, index[i]);
  222. for (j = 1; j <= 16; j++)
  223. openexif_ijg_emit_byte(cinfo, htbl->bits[j]);
  224. c = 0;
  225. for (j = 1; j <= 16; j++)
  226. for (k = 0; k < htbl->bits[j]; k++,c++)
  227. openexif_ijg_emit_byte(cinfo, htbl->huffval[c]);
  228. htbl->sent_table = TRUE;
  229. i++;
  230. }
  231. }
  232. /* Now call the original to post the rest of the frame ... */
  233. (*openexif_orig_write_scan_header)(cinfo);
  234. }
  235. #endif
  236. #endif