EncJpeg.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. /*------------------------------------------------------------------------------
  2. -- --
  3. -- This software is confidential and proprietary and may be used --
  4. -- only as expressly authorized by a licensing agreement from --
  5. -- --
  6. -- Hantro Products Oy. --
  7. -- --
  8. -- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
  9. -- ALL RIGHTS RESERVED --
  10. -- --
  11. -- The entire notice above must be reproduced --
  12. -- on all copies and should not be removed. --
  13. -- --
  14. --------------------------------------------------------------------------------
  15. --
  16. -- Abstract :
  17. --
  18. ------------------------------------------------------------------------------*/
  19. /*------------------------------------------------------------------------------
  20. Table of contents
  21. 1. Include headers
  22. 2. External compiler flags
  23. 3. Module defines
  24. 4. Local function prototypes
  25. 5. Functions
  26. ------------------------------------------------------------------------------*/
  27. /*------------------------------------------------------------------------------
  28. 1. Include headers
  29. ------------------------------------------------------------------------------*/
  30. #include "EncJpeg.h"
  31. #include "EncJpegDhtTables.h"
  32. #include "EncJpegMarkers.h"
  33. /*------------------------------------------------------------------------------
  34. 2. External compiler flags
  35. --------------------------------------------------------------------------------
  36. --------------------------------------------------------------------------------
  37. 3. Module defines
  38. ------------------------------------------------------------------------------*/
  39. static const u8 zigzag[64] = {
  40. 0, 1, 8, 16, 9, 2, 3, 10,
  41. 17, 24, 32, 25, 18, 11, 4, 5,
  42. 12, 19, 26, 33, 40, 48, 41, 34,
  43. 27, 20, 13, 6, 7, 14, 21, 28,
  44. 35, 42, 49, 56, 57, 50, 43, 36,
  45. 29, 22, 15, 23, 30, 37, 44, 51,
  46. 58, 59, 52, 45, 38, 31, 39, 46,
  47. 53, 60, 61, 54, 47, 55, 62, 63
  48. };
  49. /*------------------------------------------------------------------------------
  50. 4. Local function prototypes
  51. ------------------------------------------------------------------------------*/
  52. static void EncJpegAPP0Header(stream_s * stream, jpegData_s * data);
  53. static void EncJpegDQTHeader(stream_s * stream, jpegData_s *);
  54. static void EncJpegCOMHeader(stream_s * stream, jpegData_s *);
  55. static void EncJpegRestartInterval(stream_s * stream, jpegData_s *);
  56. static void EncJpegSOFOHeader(stream_s * stream, jpegData_s *);
  57. static void EncJpegDHTHeader(stream_s * stream, jpegData_s *);
  58. static void EncJpegSOSHeader(stream_s * stream, jpegData_s *);
  59. /*------------------------------------------------------------------------------
  60. EncJpegInit
  61. ------------------------------------------------------------------------------*/
  62. void EncJpegInit(jpegData_s * jpeg)
  63. {
  64. jpeg->header = ENCHW_NO;
  65. jpeg->restart.Ri = 0; /* Restart interval, number of MCUs */
  66. jpeg->frame.Nf = 3; /* Number of color components in a frame */
  67. jpeg->rstCount = 0;
  68. jpeg->sliceNum = 0;
  69. jpeg->codingType = ENC_WHOLE_FRAME;
  70. jpeg->markerType = ENC_SINGLE_MARKER;
  71. jpeg->appn.units = ENC_NO_UNITS;
  72. jpeg->appn.Xdensity = 1;
  73. jpeg->appn.Ydensity = 1;
  74. jpeg->com.comEnable = 0;
  75. }
  76. /*------------------------------------------------------------------------------
  77. Function name: EncJpegHdr
  78. Functional description:
  79. Inputs:
  80. Outputs:
  81. ------------------------------------------------------------------------------*/
  82. u32 EncJpegHdr(stream_s * stream, jpegData_s * data)
  83. {
  84. data->frame.Y = (u32) data->height;
  85. data->frame.X = (u32) data->width;
  86. if(data->frame.header == ENCHW_YES)
  87. {
  88. /* SOI */
  89. EncJpegHeaderPutBits(stream, SOI, 16);
  90. COMMENT("Start-Of-Image");
  91. }
  92. /* APP0 header */
  93. EncJpegAPP0Header(stream, data);
  94. if(data->frame.header == ENCHW_YES)
  95. {
  96. if(data->com.comEnable)
  97. {
  98. /* Com header */
  99. EncJpegCOMHeader(stream, data);
  100. }
  101. /* Quant header */
  102. EncJpegDQTHeader(stream, data);
  103. /* Frame header */
  104. EncJpegSOFOHeader(stream, data);
  105. /* Restart interval */
  106. EncJpegRestartInterval(stream, data);
  107. /* Huffman header */
  108. EncJpegDHTHeader(stream, data);
  109. }
  110. /* Scan header */
  111. EncJpegSOSHeader(stream, data);
  112. return (ENCHW_OK);
  113. }
  114. #if 0
  115. /*------------------------------------------------------------------------------
  116. Function name: EncJpegImageEnd
  117. Functional description:
  118. Inputs:
  119. Outputs:
  120. ------------------------------------------------------------------------------*/
  121. void EncJpegImageEnd(stream_s * stream, jpegData_s * data)
  122. {
  123. /* write EOI to stream */
  124. stream->stream[0] = 0xFF;
  125. stream->stream[1] = 0xD9;
  126. stream->byteCnt += 2;
  127. stream->stream++;
  128. stream->stream++;
  129. stream->bitCnt += 16;
  130. /* take care of next putbits */
  131. if(data->appn.thumbMode)
  132. {
  133. stream->stream[0] = 0x0;
  134. stream->stream[1] = 0x0;
  135. }
  136. COMMENT("EOI");
  137. }
  138. #endif
  139. #if 0
  140. /*------------------------------------------------------------------------------
  141. Function name: EncJpegImageEndReplaceRst
  142. Functional description: write EOI over hw set RST
  143. Inputs:
  144. Outputs:
  145. ------------------------------------------------------------------------------*/
  146. void EncJpegImageEndReplaceRst(stream_s * stream, jpegData_s * data)
  147. {
  148. COMMENT("Replace RST with EOI (slice mode)");
  149. /* write EOI to stream */
  150. stream->stream[0] = 0xFF;
  151. stream->stream[1] = 0xD9;
  152. stream->stream++;
  153. stream->stream++;
  154. /* take care of next putbits */
  155. if(data->appn.thumbMode)
  156. {
  157. stream->stream[0] = 0x0;
  158. stream->stream[1] = 0x0;
  159. }
  160. COMMENT("RST ==> EOI");
  161. }
  162. #endif
  163. /*------------------------------------------------------------------------------
  164. Function name: JpegEncAPP0Header
  165. Functional description: Sets APP0 header data
  166. Inputs:
  167. Outputs:
  168. ------------------------------------------------------------------------------*/
  169. void EncJpegAPP0Header(stream_s * stream, jpegData_s * data)
  170. {
  171. EncJpegHeaderPutBits(stream, APP0, 16);
  172. COMMENT("APP0");
  173. EncJpegHeaderPutBits(stream, 0x0010, 16);
  174. COMMENT("Length");
  175. /* "JFIF" ID */
  176. EncJpegHeaderPutBits(stream, 0x4A46, 16);
  177. COMMENT("Ident1");
  178. EncJpegHeaderPutBits(stream, 0x4946, 16);
  179. COMMENT("Ident2");
  180. EncJpegHeaderPutBits(stream, 0x00, 8);
  181. COMMENT("Ident3");
  182. EncJpegHeaderPutBits(stream, 0x0102, 16);
  183. COMMENT("Version");
  184. if(data->appn.Xdensity && data->appn.Ydensity)
  185. {
  186. EncJpegHeaderPutBits(stream, data->appn.units, 8);
  187. COMMENT("Units");
  188. EncJpegHeaderPutBits(stream, data->appn.Xdensity, 16);
  189. COMMENT("Xdensity");
  190. EncJpegHeaderPutBits(stream, data->appn.Ydensity, 16);
  191. COMMENT("Ydensity");
  192. }
  193. else
  194. {
  195. EncJpegHeaderPutBits(stream, 0x00, 8);
  196. COMMENT("Units");
  197. EncJpegHeaderPutBits(stream, 0x0001, 16);
  198. COMMENT("Xdensity");
  199. EncJpegHeaderPutBits(stream, 0x0001, 16);
  200. COMMENT("Ydensity");
  201. }
  202. EncJpegHeaderPutBits(stream, 0x00, 8);
  203. COMMENT("XThumbnail");
  204. EncJpegHeaderPutBits(stream, 0x00, 8);
  205. COMMENT("YThumbnail");
  206. /* APP0 extension header ==> thumbnail */
  207. if(data->appn.thumbEnable)
  208. {
  209. u32 length;
  210. const JpegEncThumb * thumb = &data->thumbnail;
  211. const u8 * thumbData = (u8*)thumb->data;
  212. EncJpegHeaderPutBits(stream, APP0, 16);
  213. COMMENT("APP0 Extended");
  214. /* Length of APP0 field */
  215. length = 8 + thumb->dataLength;
  216. if(thumb->format != JPEGENC_THUMB_JPEG)
  217. {
  218. length += 2; /* 2 bytes for the size */
  219. }
  220. EncJpegHeaderPutBits(stream, length, 16);
  221. COMMENT("Length");
  222. /* "JFXX" ID */
  223. EncJpegHeaderPutBits(stream, 0x4A46, 16);
  224. COMMENT("Ident1");
  225. EncJpegHeaderPutBits(stream, 0x5858, 16);
  226. COMMENT("Ident2");
  227. EncJpegHeaderPutBits(stream, 0x00, 8);
  228. COMMENT("Ident3");
  229. EncJpegHeaderPutBits(stream, (u32)thumb->format, 8);
  230. COMMENT("Extension code");
  231. if(thumb->format != JPEGENC_THUMB_JPEG)
  232. {
  233. EncJpegHeaderPutBits(stream, thumb->width, 8);
  234. COMMENT("Xthumbnail");
  235. EncJpegHeaderPutBits(stream, thumb->height, 8);
  236. COMMENT("Ythumbnail");
  237. }
  238. for(length = thumb->dataLength; length > 0; length--)
  239. {
  240. EncJpegHeaderPutBits(stream, *thumbData, 8);
  241. thumbData++;
  242. }
  243. COMMENT("Extension data");
  244. data->appn.thumbEnable = 0; /* was valid only for one picture */
  245. }
  246. }
  247. /*------------------------------------------------------------------------------
  248. Function name: EncJpegCOMHeader
  249. Functional description: Sets COM header data
  250. Inputs:
  251. Outputs:
  252. ------------------------------------------------------------------------------*/
  253. void EncJpegCOMHeader(stream_s * stream, jpegData_s * data)
  254. {
  255. u32 j;
  256. EncJpegHeaderPutBits(stream, COM, 16);
  257. COMMENT("COM");
  258. EncJpegHeaderPutBits(stream, 2 + data->com.comLen, 16);
  259. COMMENT("Lc");
  260. for(j = 0; j < data->com.comLen; j++)
  261. {
  262. /* Qk table 0 */
  263. EncJpegHeaderPutBits(stream, data->com.pComment[j], 8);
  264. COMMENT("COM data");
  265. }
  266. }
  267. /*------------------------------------------------------------------------------
  268. Function name: EncJpegDQTHeader
  269. Functional description: Sets DQT header data
  270. Inputs:
  271. Outputs:
  272. ------------------------------------------------------------------------------*/
  273. void EncJpegDQTHeader(stream_s * stream, jpegData_s * data)
  274. {
  275. u32 j;
  276. EncJpegHeaderPutBits(stream, DQT, 16);
  277. COMMENT("DQT");
  278. if(!data->markerType || data->frame.Nf == 1)
  279. {
  280. EncJpegHeaderPutBits(stream, 2 + 65, 16);
  281. COMMENT("Lq");
  282. }
  283. else
  284. {
  285. EncJpegHeaderPutBits(stream, (2 + (65 * 2)), 16);
  286. COMMENT("Lq");
  287. }
  288. EncJpegHeaderPutBits(stream, 0, 4);
  289. COMMENT("Pq");
  290. EncJpegHeaderPutBits(stream, 0, 4);
  291. COMMENT("Tq");
  292. for(j = 0; j < 64; j++)
  293. {
  294. /* Qk table 0 */
  295. EncJpegHeaderPutBits(stream, data->qTable.pQlumi[zigzag[j]], 8);
  296. COMMENT("Qk");
  297. }
  298. if(data->frame.Nf > 1)
  299. {
  300. if(!data->markerType)
  301. {
  302. EncJpegHeaderPutBits(stream, DQT, 16);
  303. COMMENT("DQT");
  304. EncJpegHeaderPutBits(stream, 2 + 65, 16);
  305. COMMENT("Lq");
  306. }
  307. EncJpegHeaderPutBits(stream, 0, 4);
  308. COMMENT("Pq");
  309. EncJpegHeaderPutBits(stream, 1, 4);
  310. COMMENT("Tq");
  311. for(j = 0; j < 64; j++)
  312. {
  313. /* Qk table 1 */
  314. EncJpegHeaderPutBits(stream, data->qTable.pQchromi[zigzag[j]], 8);
  315. COMMENT("Qk");
  316. }
  317. }
  318. }
  319. /*------------------------------------------------------------------------------
  320. Function name: EncJpegRestartInterval
  321. Functional description: Sets DRI header data
  322. Inputs:
  323. Outputs:
  324. ------------------------------------------------------------------------------*/
  325. void EncJpegRestartInterval(stream_s * stream, jpegData_s * data)
  326. {
  327. if(data->restart.Ri != 0)
  328. {
  329. EncJpegHeaderPutBits(stream, DRI, 16);
  330. COMMENT("DRI");
  331. data->restart.Lr = 4;
  332. EncJpegHeaderPutBits(stream, data->restart.Lr, 16);
  333. COMMENT("Lr");
  334. EncJpegHeaderPutBits(stream, data->restart.Ri, 16);
  335. COMMENT("Rq");
  336. }
  337. }
  338. /*------------------------------------------------------------------------------
  339. Function name: EncJpegFrameHeader
  340. Functional description: Sets Frame header data
  341. Inputs:
  342. Outputs:
  343. ------------------------------------------------------------------------------*/
  344. void EncJpegSOFOHeader(stream_s * stream, jpegData_s * data)
  345. {
  346. u32 i;
  347. ASSERT(data->frame.Nf <= MAX_NUMBER_OF_COMPONENTS);
  348. /* SOF0 */
  349. EncJpegHeaderPutBits(stream, SOF0, 16);
  350. COMMENT("SOF0");
  351. /* Frame header */
  352. data->frame.Lf = (8 + (3 * data->frame.Nf));
  353. data->frame.P = 8;
  354. EncJpegHeaderPutBits(stream, data->frame.Lf, 16);
  355. COMMENT("Lf");
  356. EncJpegHeaderPutBits(stream, data->frame.P, 8);
  357. COMMENT("P");
  358. EncJpegHeaderPutBits(stream, data->frame.Y, 16);
  359. COMMENT("Y");
  360. EncJpegHeaderPutBits(stream, data->frame.X, 16);
  361. COMMENT("X");
  362. EncJpegHeaderPutBits(stream, data->frame.Nf, 8);
  363. COMMENT("Nf");
  364. /* Only 1 component, grayscale */
  365. if(data->frame.Nf == 1)
  366. {
  367. data->frame.Ci[0] = 1;
  368. data->frame.Hi[0] = 1;
  369. data->frame.Vi[0] = 1;
  370. data->frame.Tqi[0] = 0;
  371. }
  372. /* 3 components */
  373. if(data->frame.Nf == 3)
  374. {
  375. if (data->codingMode == ENC_420_MODE)
  376. {
  377. /* YUV 4:2:0 */
  378. data->frame.Ci[0] = 1;
  379. data->frame.Hi[0] = 2;
  380. data->frame.Vi[0] = 2;
  381. data->frame.Tqi[0] = 0;
  382. data->frame.Ci[1] = 2;
  383. data->frame.Hi[1] = 1;
  384. data->frame.Vi[1] = 1;
  385. data->frame.Tqi[1] = 1;
  386. data->frame.Ci[2] = 3;
  387. data->frame.Hi[2] = 1;
  388. data->frame.Vi[2] = 1;
  389. data->frame.Tqi[2] = 1;
  390. }
  391. else
  392. {
  393. /* YUV 4:2:2, MCU = 2 luma blocks + cb block + cr block */
  394. data->frame.Ci[0] = 1;
  395. data->frame.Hi[0] = 2;
  396. data->frame.Vi[0] = 1;
  397. data->frame.Tqi[0] = 0;
  398. data->frame.Ci[1] = 2;
  399. data->frame.Hi[1] = 1;
  400. data->frame.Vi[1] = 1;
  401. data->frame.Tqi[1] = 1;
  402. data->frame.Ci[2] = 3;
  403. data->frame.Hi[2] = 1;
  404. data->frame.Vi[2] = 1;
  405. data->frame.Tqi[2] = 1;
  406. }
  407. }
  408. for(i = 0; i < data->frame.Nf; i++)
  409. {
  410. EncJpegHeaderPutBits(stream, data->frame.Ci[i], 8);
  411. COMMENT("Ci");
  412. EncJpegHeaderPutBits(stream, data->frame.Hi[i], 4);
  413. COMMENT("Hi");
  414. EncJpegHeaderPutBits(stream, data->frame.Vi[i], 4);
  415. COMMENT("Vi");
  416. EncJpegHeaderPutBits(stream, data->frame.Tqi[i], 8);
  417. COMMENT("Tqi");
  418. }
  419. }
  420. /*------------------------------------------------------------------------------
  421. Function name: EncJpegDHTHeader
  422. Functional description: Sets DHT header data
  423. Inputs:
  424. Outputs:
  425. ------------------------------------------------------------------------------*/
  426. void EncJpegDHTHeader(stream_s * stream, jpegData_s * data)
  427. {
  428. u32 dc_lum, dc_chrom;
  429. u32 ac_lum, ac_chrom;
  430. u32 dc_vij, ac_vij;
  431. ASSERT(data->frame.Nf <= MAX_NUMBER_OF_COMPONENTS);
  432. if(data->frame.Nf == 1)
  433. {
  434. /* DHT */
  435. EncJpegHeaderPutBits(stream, DHT, 16);
  436. COMMENT("DHT");
  437. /* Lh */
  438. EncJpegHeaderPutBits(stream, 2 + ((17 * 2) + ((1 * 12) + (1 * 162))),
  439. 16);
  440. COMMENT("Lh");
  441. /* Huffman tables for luminance DC and AC components */
  442. /* TC */
  443. EncJpegHeaderPutBits(stream, 0, 4);
  444. COMMENT("TC");
  445. /* TH */
  446. EncJpegHeaderPutBits(stream, 0, 4);
  447. COMMENT("TH");
  448. for(dc_lum = 0; dc_lum < 16; dc_lum++)
  449. {
  450. EncJpegHeaderPutBits(stream, Dc_Li[dc_lum].DcLumLi, 8);
  451. COMMENT("Dc_Li");
  452. }
  453. for(dc_vij = 0; dc_vij < 12; dc_vij++)
  454. {
  455. EncJpegHeaderPutBits(stream, Vij_Dc[dc_vij].DcLumVij, 8);
  456. COMMENT("Vij_Dc");
  457. }
  458. /* TC */
  459. EncJpegHeaderPutBits(stream, 1, 4);
  460. COMMENT("TC");
  461. /* TH */
  462. EncJpegHeaderPutBits(stream, 0, 4);
  463. COMMENT("TH");
  464. for(ac_lum = 0; ac_lum < 16; ac_lum++)
  465. {
  466. EncJpegHeaderPutBits(stream, Ac_Li[ac_lum].AcLumLi, 8);
  467. COMMENT("Ac_Li");
  468. }
  469. for(ac_vij = 0; ac_vij < 162; ac_vij++)
  470. {
  471. EncJpegHeaderPutBits(stream, Vij_Ac[ac_vij].AcLumVij, 8);
  472. COMMENT("Vij_Ac");
  473. }
  474. }
  475. else
  476. {
  477. /* DHT */
  478. EncJpegHeaderPutBits(stream, DHT, 16);
  479. COMMENT("DHT");
  480. /* Huffman table for luminance DC components */
  481. /* Lh */
  482. if(!data->markerType)
  483. {
  484. EncJpegHeaderPutBits(stream, 2 + ((17 * 1) + ((1 * 12))), 16);
  485. COMMENT("Lh");
  486. }
  487. else
  488. {
  489. EncJpegHeaderPutBits(stream,
  490. (2 + ((17 * 4) + ((2 * 12) + (2 * 162)))), 16);
  491. COMMENT("Lh");
  492. }
  493. /* TC */
  494. EncJpegHeaderPutBits(stream, 0, 4);
  495. COMMENT("TC");
  496. /* TH */
  497. EncJpegHeaderPutBits(stream, 0, 4);
  498. COMMENT("TH");
  499. for(dc_lum = 0; dc_lum < 16; dc_lum++)
  500. {
  501. EncJpegHeaderPutBits(stream, Dc_Li[dc_lum].DcLumLi, 8);
  502. COMMENT("Dc_Li");
  503. }
  504. for(dc_vij = 0; dc_vij < 12; dc_vij++)
  505. {
  506. EncJpegHeaderPutBits(stream, Vij_Dc[dc_vij].DcLumVij, 8);
  507. COMMENT("Vij_Dc");
  508. }
  509. if(!data->markerType)
  510. {
  511. /* DHT */
  512. EncJpegHeaderPutBits(stream, DHT, 16);
  513. COMMENT("DHT");
  514. /* Huffman table for luminance AC components */
  515. /* Lh */
  516. EncJpegHeaderPutBits(stream, 2 + ((17 * 1) + ((1 * 162))), 16);
  517. COMMENT("Lh");
  518. }
  519. /* TC */
  520. EncJpegHeaderPutBits(stream, 1, 4);
  521. COMMENT("TC");
  522. /* TH */
  523. EncJpegHeaderPutBits(stream, 0, 4);
  524. COMMENT("TH");
  525. for(ac_lum = 0; ac_lum < 16; ac_lum++)
  526. {
  527. EncJpegHeaderPutBits(stream, Ac_Li[ac_lum].AcLumLi, 8);
  528. COMMENT("Ac_Li");
  529. }
  530. for(ac_vij = 0; ac_vij < 162; ac_vij++)
  531. {
  532. EncJpegHeaderPutBits(stream, Vij_Ac[ac_vij].AcLumVij, 8);
  533. COMMENT("Vij_Ac");
  534. }
  535. /* Huffman table for chrominance DC components */
  536. if(!data->markerType)
  537. {
  538. /* DHT */
  539. EncJpegHeaderPutBits(stream, DHT, 16);
  540. COMMENT("DHT");
  541. /* Lh */
  542. EncJpegHeaderPutBits(stream, 2 + ((17 * 1) + ((1 * 12))), 16);
  543. COMMENT("Lh");
  544. }
  545. /* TC */
  546. EncJpegHeaderPutBits(stream, 0, 4);
  547. COMMENT("TC");
  548. /* TH */
  549. EncJpegHeaderPutBits(stream, 1, 4);
  550. COMMENT("TH");
  551. for(dc_chrom = 0; dc_chrom < 16; dc_chrom++)
  552. {
  553. EncJpegHeaderPutBits(stream, Dc_Li[dc_chrom].DcChromLi, 8);
  554. COMMENT("Dc_Li");
  555. }
  556. for(dc_vij = 0; dc_vij < 12; dc_vij++)
  557. {
  558. EncJpegHeaderPutBits(stream, Vij_Dc[dc_vij].DcChromVij, 8);
  559. COMMENT("Vij_Dc");
  560. }
  561. /* Huffman table for chrominance AC components */
  562. if(!data->markerType)
  563. {
  564. /* DHT */
  565. EncJpegHeaderPutBits(stream, DHT, 16);
  566. COMMENT("DHT");
  567. /* Lh */
  568. EncJpegHeaderPutBits(stream, 2 + ((17 * 1) + ((1 * 162))), 16);
  569. COMMENT("Lh");
  570. }
  571. /* TC */
  572. EncJpegHeaderPutBits(stream, 1, 4);
  573. COMMENT("TC");
  574. /* TH */
  575. EncJpegHeaderPutBits(stream, 1, 4);
  576. COMMENT("TH");
  577. for(ac_chrom = 0; ac_chrom < 16; ac_chrom++)
  578. {
  579. EncJpegHeaderPutBits(stream, Ac_Li[ac_chrom].AcChromLi, 8);
  580. COMMENT("Ac_Li");
  581. }
  582. for(ac_vij = 0; ac_vij < 162; ac_vij++)
  583. {
  584. EncJpegHeaderPutBits(stream, Vij_Ac[ac_vij].AcChromVij, 8);
  585. COMMENT("Vij_Ac");
  586. }
  587. }
  588. }
  589. /*------------------------------------------------------------------------------
  590. Function name: EncJpegSOSHeader
  591. Functional description: Sets SOS header data
  592. Inputs:
  593. Outputs:
  594. ------------------------------------------------------------------------------*/
  595. void EncJpegSOSHeader(stream_s * stream, jpegData_s * data)
  596. {
  597. u32 i;
  598. u32 Ns, Ls;
  599. /* SOS */
  600. EncJpegHeaderPutBits(stream, SOS, 16);
  601. COMMENT("SOS");
  602. Ns = data->frame.Nf;
  603. Ls = (6 + (2 * Ns));
  604. EncJpegHeaderPutBits(stream, Ls, 16);
  605. COMMENT("Ls");
  606. EncJpegHeaderPutBits(stream, Ns, 8);
  607. COMMENT("Ns");
  608. for(i = 0; i < Ns; i++)
  609. {
  610. /* Csj */
  611. EncJpegHeaderPutBits(stream, i + 1, 8);
  612. COMMENT("Csj");
  613. if(i == 0)
  614. {
  615. /* Tdj */
  616. EncJpegHeaderPutBits(stream, 0, 4);
  617. COMMENT("Tdj");
  618. /* Taj */
  619. EncJpegHeaderPutBits(stream, 0, 4);
  620. COMMENT("Taj");
  621. }
  622. else
  623. {
  624. /* Tdj */
  625. EncJpegHeaderPutBits(stream, 1, 4);
  626. COMMENT("Tdj");
  627. /* Taj */
  628. EncJpegHeaderPutBits(stream, 1, 4);
  629. COMMENT("Taj");
  630. }
  631. }
  632. /* Ss */
  633. EncJpegHeaderPutBits(stream, 0, 8);
  634. COMMENT("Ss");
  635. /* Se */
  636. EncJpegHeaderPutBits(stream, 63, 8);
  637. COMMENT("Se");
  638. /* Ah */
  639. EncJpegHeaderPutBits(stream, 0, 4);
  640. COMMENT("Ah");
  641. /* Al */
  642. EncJpegHeaderPutBits(stream, 0, 4);
  643. COMMENT("Al");
  644. }