iljpgencodejif.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these librararies and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: iljpgencodejif.c /main/3 1995/10/23 15:56:46 rswiston $ */
  24. /**---------------------------------------------------------------------
  25. ***
  26. *** (c)Copyright 1992 Hewlett-Packard Co.
  27. ***
  28. *** RESTRICTED RIGHTS LEGEND
  29. *** Use, duplication, or disclosure by the U.S. Government is subject to
  30. *** restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in
  31. *** Technical Data and Computer Software clause in DFARS 252.227-7013.
  32. *** Hewlett-Packard Company
  33. *** 3000 Hanover Street
  34. *** Palo Alto, CA 94304 U.S.A.
  35. *** Rights for non-DOD U.S. Government Departments and Agencies are as set
  36. *** forth in FAR 52.227-19(c)(1,2).
  37. ***
  38. ***-------------------------------------------------------------------*/
  39. #include "iljpgencodeint.h"
  40. /* -------------------- iljpgPut2Bytes -------------------------- */
  41. /* Put 2 bytes of "value" (which is really a short) to the given stream
  42. in big endian order, as defined for 16 bit values for JIF.
  43. */
  44. static iljpgError iljpgPut2Bytes (
  45. int value,
  46. ILJPG_ENCODE_STREAM stream
  47. )
  48. {
  49. ilByte abyte;
  50. iljpgError error;
  51. abyte = (value >> 8) & 0xff;
  52. if (!ILJPG_ENCODE_PUT_BYTE (stream, abyte, error))
  53. return error;
  54. abyte = value & 0xff;
  55. if (!ILJPG_ENCODE_PUT_BYTE (stream, abyte, error))
  56. return error;
  57. return 0;
  58. }
  59. /* -------------------- iljpgEncodePutBytes -------------------------- */
  60. /* Put "nBytes" bytes pointed to by "pBytes" to the given stream.
  61. */
  62. static iljpgError iljpgEncodePutBytes (
  63. iljpgPtr pBytes,
  64. int nBytes,
  65. ILJPG_ENCODE_STREAM stream
  66. )
  67. {
  68. ilByte abyte;
  69. iljpgError error;
  70. while (nBytes-- > 0) {
  71. abyte = *pBytes++;
  72. if (!ILJPG_ENCODE_PUT_BYTE (stream, abyte, error))
  73. return error;
  74. }
  75. return 0;
  76. }
  77. /* -------------------- iljpgWriteHuffmanTable -------------------------- */
  78. /* Write the Huffman table pointed to by "pTable" to the given stream.
  79. "Th" is the table identifier: 0..3 for DC table, 16..19 for AC table.
  80. */
  81. static iljpgError iljpgWriteHuffmanTable (
  82. iljpgPtr pTable,
  83. int Th,
  84. ILJPG_ENCODE_STREAM stream
  85. )
  86. {
  87. register int i, nBytes;
  88. iljpgError error;
  89. /* Huffman tables are: 16 bytes of # occurrences each # bits, followed by
  90. bytes for each of those # occurrences. Size of table = 16 + sum(0..15).
  91. */
  92. for (i = 0, nBytes = 16; i < 16; i++)
  93. nBytes += pTable[i];
  94. if (!ILJPG_ENCODE_PUT_BYTE (stream, ILJPGM_FIRST_BYTE, error))
  95. return error;
  96. if (!ILJPG_ENCODE_PUT_BYTE (stream, ILJPGM_DHT, error))
  97. return error;
  98. /* Write length = 2 (length) + 1 (Th) + nBytes (16 bytes + variable length) */
  99. if (error = iljpgPut2Bytes (3 + nBytes, stream))
  100. return error;
  101. if (!ILJPG_ENCODE_PUT_BYTE (stream, Th, error))
  102. return error;
  103. if (error = iljpgEncodePutBytes (pTable, nBytes, stream))
  104. return error;
  105. return 0;
  106. }
  107. /* -------------------- iljpgEncodeJIF -------------------------- */
  108. /* Write a JIF (JPEG Interchange Format) header to the given "stream"
  109. given a data block (same as returned by iljpgDecodeJIF()) pointed
  110. to by "pData", defining the tables, etc. The stream is left
  111. positioned after the Scan header (SOS); the compressed data should
  112. be written right after that.
  113. If "pOffsets" is non-null the offsets within the stream where
  114. various items were output are returned.
  115. */
  116. ILJPG_PUBLIC iljpgError iljpgEncodeJIF (
  117. ILJPG_ENCODE_STREAM stream,
  118. iljpgDataPtr pData,
  119. iljpgJIFOffsetsPtr pOffsets
  120. )
  121. {
  122. register int index, i;
  123. register iljpgPtr pTable;
  124. register iljpgError error;
  125. register iljpgCompDataPtr pComp;
  126. long startOffset;
  127. # define PUT_BYTE(_byte) { \
  128. if (!ILJPG_ENCODE_PUT_BYTE (stream, _byte, error)) \
  129. goto JIFError; \
  130. }
  131. # define PUT_2BYTES(_value) { \
  132. if (error = iljpgPut2Bytes (_value, stream)) \
  133. goto JIFError; \
  134. }
  135. /* Write a single frame, single scan JIF image. The format will be:
  136. SOI
  137. <quant tables> = one or more DQTs
  138. <frame> = SOF0 ...
  139. <Huffman tables> = one or more DHTs
  140. <scan> = SOS ...
  141. <data> (not written - stream left positioned here)
  142. Note that the order of the tables could be different but this is how JFIF
  143. files have the tables and other readers may require it.
  144. When writing length, remember that the length includes
  145. the size of the length itself, = 2 (bytes).
  146. */
  147. /* If offsets to be returned save starting offset and init values to 0 */
  148. if (pOffsets) {
  149. startOffset = ILJPG_ENCODE_OFFSET(stream);
  150. for (i = 0; i < 4; i++) {
  151. pOffsets->QTables[i] = 0;
  152. pOffsets->DCTables[i] = 0;
  153. pOffsets->ACTables[i] = 0;
  154. }
  155. }
  156. /* Write SOI marker */
  157. PUT_BYTE (ILJPGM_FIRST_BYTE)
  158. PUT_BYTE (ILJPGM_SOI)
  159. /* Write a DRI (restart interval) marker if restartInterval non-zero */
  160. if (pData->restartInterval) {
  161. PUT_BYTE (ILJPGM_FIRST_BYTE)
  162. PUT_BYTE (ILJPGM_DRI)
  163. PUT_2BYTES (4) /* length = 4 bytes */
  164. PUT_2BYTES (pData->restartInterval) /* restart interval */
  165. }
  166. /* Write DQT and quantization tables for all non-null tables.
  167. Note that Q tables must already be in zigzag order.
  168. */
  169. for (index = 0; index < 4; index++) {
  170. if (pTable = pData->QTables[index]) {
  171. PUT_BYTE (ILJPGM_FIRST_BYTE)
  172. PUT_BYTE (ILJPGM_DQT)
  173. PUT_2BYTES (67) /* length = 67 bytes */
  174. PUT_BYTE (index) /* Pq = 0; Tq (id) = index */
  175. if (pOffsets)
  176. pOffsets->QTables[index] = ILJPG_ENCODE_OFFSET(stream) - startOffset;
  177. if (error = iljpgEncodePutBytes (pTable, 64, stream))
  178. goto JIFError;
  179. }
  180. }
  181. /* Write frame (SOF0) */
  182. PUT_BYTE (ILJPGM_FIRST_BYTE)
  183. PUT_BYTE (ILJPGM_SOF0)
  184. PUT_2BYTES (8 + 3 * pData->nComps) /* length = 8 + 3 * # components */
  185. PUT_BYTE (8) /* P = precision = 8 for baseline */
  186. PUT_2BYTES (pData->height) /* Y = # of lines = image height */
  187. PUT_2BYTES (pData->width) /* X = # of samples = image width */
  188. PUT_BYTE (pData->nComps) /* Ns = # of components */
  189. /* Write per-component frame data: id is arbitrary unique id (0..255).
  190. However, a bug in the IL's imageutil (ilujfif.c) required that the
  191. component ids be 1..3 for samples 0..2. So use use "index" + 1; also below.
  192. Write hori/vert sample factor, Q table selector (QTableIndex).
  193. */
  194. for (index = 0, pComp = pData->comp; index < pData->nComps; index++, pComp++) {
  195. PUT_BYTE (index + 1) /* id = component index; see above */
  196. i = (pComp->horiFactor << 4) | pComp->vertFactor;
  197. PUT_BYTE (i) /* Hi/Vi = hori/vert sample factors */
  198. PUT_BYTE (pComp->QTableIndex) /* Tq = Q table selector */
  199. }
  200. /* Write DHT and Huffman tables for all non-null tables.
  201. The DC tables have ids = index (0..3 - really, 0..1 for baseline)
  202. while the AC tables have ids = index + 16 (16..17).
  203. Add "5" to offsets; 5 bytes (marker, length, Th) written before code lengths.
  204. */
  205. for (index = 0; index < 4; index++) {
  206. if (pTable = pData->DCTables[index]) {
  207. if (pOffsets)
  208. pOffsets->DCTables[index] = ILJPG_ENCODE_OFFSET(stream) - startOffset + 5;
  209. if (error = iljpgWriteHuffmanTable (pTable, index, stream))
  210. goto JIFError;
  211. }
  212. }
  213. for (index = 0; index < 4; index++) {
  214. if (pTable = pData->ACTables[index]) {
  215. if (pOffsets)
  216. pOffsets->ACTables[index] = ILJPG_ENCODE_OFFSET(stream) - startOffset + 5;
  217. if (error = iljpgWriteHuffmanTable (pTable, 16 + index, stream))
  218. goto JIFError;
  219. }
  220. }
  221. /* Write scan (SOS); the actual compressed data follows this */
  222. PUT_BYTE (ILJPGM_FIRST_BYTE)
  223. PUT_BYTE (ILJPGM_SOS)
  224. PUT_2BYTES (6 + 2 * pData->nComps) /* length = 6 + 2 * # components */
  225. PUT_BYTE (pData->nComps) /* Ns = # of components */
  226. /* Write per-component frame data: scan component selector, = id in
  227. frame, = index+1; Td/Ta = DC/AC table selector = DC/AC table index (0..1).
  228. */
  229. for (index = 0, pComp = pData->comp; index < pData->nComps; index++, pComp++) {
  230. PUT_BYTE (index + 1) /* id; see notes for frame header */
  231. i = (pComp->DCTableIndex << 4) | pComp->ACTableIndex;
  232. PUT_BYTE (i) /* Hi/Vi = hori/vert sample factors */
  233. }
  234. /* Write Ss, Se and Ah/Al to finish off scan header */
  235. PUT_BYTE (0) /* Ss = 0 for baseline */
  236. PUT_BYTE (63) /* Se = 63 for baseline */
  237. PUT_BYTE (0) /* Ah = 0, 1st scan; Al = 0, baseline */
  238. /* Branch point if other error; return "error" */
  239. JIFError:
  240. return error;
  241. }