jpeg.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /* vim: tabstop=4 shiftwidth=4 noexpandtab
  2. * This file is part of ToaruOS and is released under the terms
  3. * of the NCSA / University of Illinois License - see LICENSE.md
  4. * Copyright (C) 2018 K. Lange
  5. *
  6. * libtoaru_jpeg: Decode simple JPEGs.
  7. *
  8. * Adapted from Raul Aguaviva's Python "micro JPEG visualizer":
  9. *
  10. * MIT License
  11. *
  12. * Copyright (c) 2017 Raul Aguaviva
  13. *
  14. * Permission is hereby granted, free of charge, to any person obtaining a copy
  15. * of this software and associated documentation files (the "Software"), to deal
  16. * in the Software without restriction, including without limitation the rights
  17. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  18. * copies of the Software, and to permit persons to whom the Software is
  19. * furnished to do so, subject to the following conditions:
  20. *
  21. * The above copyright notice and this permission notice shall be included in all
  22. * copies or substantial portions of the Software.
  23. *
  24. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  26. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  27. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  28. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  29. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30. * SOFTWARE.
  31. *
  32. */
  33. #include <stdint.h>
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <math.h>
  38. #include <toaru/graphics.h>
  39. #ifndef NO_SSE
  40. #include <xmmintrin.h>
  41. #include <emmintrin.h>
  42. #endif
  43. #if 0
  44. #include <toaru/trace.h>
  45. #define TRACE_APP_NAME "jpeg"
  46. #else
  47. #define TRACE(...)
  48. #endif
  49. static sprite_t * sprite = NULL;
  50. /* Byte swap short (because JPEG uses big-endian values) */
  51. static void swap16(uint16_t * val) {
  52. char * a = (char *)val;
  53. char b = a[0];
  54. a[0] = a[1];
  55. a[1] = b;
  56. }
  57. /* JPEG compontent zig-zag ordering */
  58. static int zigzag[] = {
  59. 0, 1, 8, 16, 9, 2, 3, 10,
  60. 17, 24, 32, 25, 18, 11, 4, 5,
  61. 12, 19, 26, 33, 40, 48, 41, 34,
  62. 27, 20, 13, 6, 7, 14, 21, 28,
  63. 35, 42, 49, 56, 57, 50, 43, 36,
  64. 29, 22, 15, 23, 30, 37, 44, 51,
  65. 58, 59, 52, 45, 38, 31, 39, 46,
  66. 53, 60, 61, 54, 47, 55, 62, 63
  67. };
  68. static uint8_t quant_mapping[3] = {0};
  69. static uint8_t quant[8][64];
  70. static int clamp(int col) {
  71. if (col > 255) return 255;
  72. if (col < 0) return 0;
  73. return col;
  74. }
  75. /* YCbCr to RGB conversion */
  76. static void color_conversion(
  77. float Y, float Cb, float Cr,
  78. int *R, int *G, int *B
  79. ) {
  80. float r = (Cr*(2.0-2.0*0.299) + Y);
  81. float b = (Cb*(2.0-2.0*0.114) + Y);
  82. float g = (Y - 0.144 * b - 0.229 * r) / 0.587;
  83. *R = clamp(r + 128);
  84. *G = clamp(g + 128);
  85. *B = clamp(b + 128);
  86. }
  87. static int xy_to_lin(int x, int y) {
  88. return x + y * 8;
  89. }
  90. struct huffman_table {
  91. uint8_t lengths[16];
  92. uint8_t elements[256];
  93. } huffman_tables[256] = {0};
  94. struct stream {
  95. FILE * file;
  96. uint8_t byte;
  97. int have;
  98. int pos;
  99. };
  100. static void define_quant_table(FILE * f, int len) {
  101. TRACE("Defining quant table");
  102. while (len > 0) {
  103. uint8_t hdr;
  104. fread(&hdr, 1, 1, f);
  105. fread(&quant[(hdr) & 0xF], 64, 1, f);
  106. len -= 65;
  107. }
  108. TRACE("Done");
  109. }
  110. static void baseline_dct(FILE * f, int len) {
  111. struct dct {
  112. uint8_t hdr;
  113. uint16_t height;
  114. uint16_t width;
  115. uint8_t components;
  116. } __attribute__((packed)) dct;
  117. fread(&dct, sizeof(struct dct), 1, f);
  118. /* Read image dimensions, each as big-endian 16-bit values */
  119. swap16(&dct.height);
  120. swap16(&dct.width);
  121. /* We read 7 bytes */
  122. len -= sizeof(struct dct);
  123. TRACE("Image dimensions are %d×%d", dct.width, dct.height);
  124. sprite->width = dct.width;
  125. sprite->height = dct.height;
  126. sprite->bitmap = malloc(sizeof(uint32_t) * sprite->width * sprite->height);
  127. sprite->masks = NULL;
  128. sprite->alpha = 0;
  129. sprite->blank = 0;
  130. TRACE("Loading quantization mappings...");
  131. for (int i = 0; i < dct.components; ++i) {
  132. /* Quant mapping */
  133. struct {
  134. uint8_t id;
  135. uint8_t samp;
  136. uint8_t qtb_id;
  137. } __attribute__((packed)) tmp;
  138. fread(&tmp, sizeof(tmp), 1, f);
  139. /* There should only be three of these for the images we support. */
  140. if (i > 3) {
  141. abort();
  142. }
  143. quant_mapping[i] = tmp.qtb_id;
  144. /* 3 bytes were read */
  145. len -= 3;
  146. }
  147. /* Skip whatever else might be in this section */
  148. if (len > 0) {
  149. fseek(f, len, SEEK_CUR);
  150. }
  151. }
  152. static void define_huffman_table(FILE * f, int len) {
  153. TRACE("Loading Huffman tables...");
  154. while (len > 0) {
  155. /* Read header ID */
  156. uint8_t hdr;
  157. fread(&hdr, 1, 1, f);
  158. len--;
  159. /* Read length table */
  160. fread(huffman_tables[hdr].lengths, 16, 1, f);
  161. len -= 16;
  162. /* Read Huffman table entries */
  163. int o = 0;
  164. for (int i = 0; i < 16; ++i) {
  165. int l = huffman_tables[hdr].lengths[i];
  166. fread(&huffman_tables[hdr].elements[o], l, 1, f);
  167. o += l;
  168. len -= l;
  169. }
  170. }
  171. /* Skip rest of section */
  172. if (len > 0) {
  173. fseek(f, len, SEEK_CUR);
  174. }
  175. }
  176. struct idct {
  177. float base[64];
  178. };
  179. /**
  180. * norm_coeff[0] = 0.35355339059
  181. * norm_coeff[1] = 0.5
  182. */
  183. static float cosines[8][8] = {
  184. { 0.35355339059,0.35355339059,0.35355339059,0.35355339059,0.35355339059,0.35355339059,0.35355339059,0.35355339059 },
  185. { 0.490392640202,0.415734806151,0.27778511651,0.0975451610081,-0.0975451610081,-0.27778511651,-0.415734806151,-0.490392640202 },
  186. { 0.461939766256,0.191341716183,-0.191341716183,-0.461939766256,-0.461939766256,-0.191341716183,0.191341716183,0.461939766256 },
  187. { 0.415734806151,-0.0975451610081,-0.490392640202,-0.27778511651,0.27778511651,0.490392640202,0.0975451610081,-0.415734806151 },
  188. { 0.353553390593,-0.353553390593,-0.353553390593,0.353553390593,0.353553390593,-0.353553390593,-0.353553390593,0.353553390593 },
  189. { 0.27778511651,-0.490392640202,0.0975451610081,0.415734806151,-0.415734806151,-0.0975451610081,0.490392640202,-0.27778511651 },
  190. { 0.191341716183,-0.461939766256,0.461939766256,-0.191341716183,-0.191341716183,0.461939766256,-0.461939766256,0.191341716183 },
  191. { 0.0975451610081,-0.27778511651,0.415734806151,-0.490392640202,0.490392640202,-0.415734806151,0.27778511651,-0.0975451610081 },
  192. };
  193. static float premul[8][8][8][8]= {{{{0}}}};
  194. static void add_idc(struct idct * self, int n, int m, int coeff) {
  195. #ifdef NO_SSE
  196. for (int y = 0; y < 8; ++y) {
  197. for (int x = 0; x < 8; ++x) {
  198. self->base[xy_to_lin(x, y)] += premul[n][m][y][x] * coeff;
  199. }
  200. }
  201. #else
  202. __m128 c = _mm_set_ps(coeff,coeff,coeff,coeff);
  203. for (int y = 0; y < 8; ++y) {
  204. __m128 a, b;
  205. /* base[y][x] = base[y][x] + premul[n][m][y][x] * coeff */
  206. /* x = 0..3 */
  207. a = _mm_load_ps(&premul[n][m][y][0]);
  208. a = _mm_mul_ps(a,c);
  209. b = _mm_load_ps(&self->base[xy_to_lin(0,y)]);
  210. a = _mm_add_ps(a,b);
  211. _mm_store_ps(&self->base[xy_to_lin(0,y)], a);
  212. /* x = 4..7 */
  213. a = _mm_load_ps(&premul[n][m][y][4]);
  214. a = _mm_mul_ps(a,c);
  215. b = _mm_load_ps(&self->base[xy_to_lin(4,y)]);
  216. a = _mm_add_ps(a,b);
  217. _mm_store_ps(&self->base[xy_to_lin(4,y)], a);
  218. }
  219. #endif
  220. }
  221. static void add_zigzag(struct idct * self, int zi, int coeff) {
  222. int i = zigzag[zi];
  223. int n = i & 0x7;
  224. int m = i >> 3;
  225. add_idc(self, n, m, coeff);
  226. }
  227. /* Read a bit from the stream */
  228. static int get_bit(struct stream * st) {
  229. while ((st->pos >> 3) >= st->have) {
  230. /* We have finished using the current byte and need to read another one */
  231. int t = fgetc(st->file);
  232. if (t < 0) {
  233. /* EOF */
  234. st->byte = 0;
  235. } else {
  236. st->byte = t;
  237. }
  238. if (st->byte == 0xFF) {
  239. /*
  240. * If we see 0xFF, it's followed by a 0x00
  241. * that should be skipped.
  242. */
  243. int tmp = fgetc(st->file);
  244. if (tmp != 0) {
  245. /*
  246. * If it's *not*, we reached the end of the file - but
  247. * this shouldn't happen.
  248. */
  249. st->byte = 0;
  250. }
  251. }
  252. /* We've seen a new byte */
  253. st->have++;
  254. }
  255. /* Extract appropriate bit from this byte */
  256. uint8_t b = st->byte;
  257. int s = 7 - (st->pos & 0x7);
  258. /* We move forward one position in the bit stream */
  259. st->pos += 1;
  260. return (b >> s) & 1;
  261. }
  262. /* Advance forward and get the n'th next bit */
  263. static int get_bitn(struct stream * st, int l) {
  264. int val = 0;
  265. for (int i = 0; i < l; ++i) {
  266. val = val * 2 + get_bit(st);
  267. }
  268. return val;
  269. }
  270. /*
  271. * Read a Huffman code by reading bits and using
  272. * the Huffman table.
  273. */
  274. static int get_code(struct huffman_table * table, struct stream * st) {
  275. int val = 0;
  276. int off = 0;
  277. int ini = 0;
  278. for (int i = 0; i < 16; ++i) {
  279. val = val * 2 + get_bit(st);
  280. if (table->lengths[i] > 0) {
  281. if (val - ini < table->lengths[i]) {
  282. return table->elements[off + val - ini];
  283. }
  284. ini = ini + table->lengths[i];
  285. off += table->lengths[i];
  286. }
  287. ini *= 2;
  288. }
  289. /* Invalid */
  290. return -1;
  291. }
  292. /* Decode Huffman codes to values */
  293. static int decode(int code, int bits) {
  294. int l = 1L << (code - 1);
  295. if (bits >= l) {
  296. return bits;
  297. } else {
  298. return bits - (2 * l - 1);
  299. }
  300. }
  301. /* Build IDCT matrix */
  302. static struct idct * build_matrix(struct idct * i, struct stream * st, int idx, uint8_t * quant, int oldcoeff, int * outcoeff) {
  303. memset(i, 0, sizeof(struct idct));
  304. int code = get_code(&huffman_tables[idx], st);
  305. int bits = get_bitn(st, code);
  306. int dccoeff = decode(code, bits) + oldcoeff;
  307. add_zigzag(i, 0, dccoeff * quant[0]);
  308. int l = 1;
  309. while (l < 64) {
  310. code = get_code(&huffman_tables[16+idx], st);
  311. if (code == 0) break;
  312. if (code > 15) {
  313. l += (code >> 4);
  314. code = code & 0xF;
  315. }
  316. bits = get_bitn(st, code);
  317. int coeff = decode(code, bits);
  318. add_zigzag(i, l, coeff * quant[l]);
  319. l += 1;
  320. }
  321. *outcoeff = dccoeff;
  322. return i;
  323. }
  324. /* Set pixel in sprite buffer with bounds checking */
  325. static void set_pixel(int x, int y, uint32_t color) {
  326. if ((x < sprite->width) && (y < sprite->height)) {
  327. SPRITE(sprite,x,y) = color;
  328. }
  329. }
  330. /* Concvert YCbCr values to RGB pixels */
  331. static void draw_matrix(int x, int y, struct idct * L, struct idct * cb, struct idct * cr) {
  332. for (int yy = 0; yy < 8; ++yy) {
  333. for (int xx = 0; xx < 8; ++xx) {
  334. int o = xy_to_lin(xx,yy);
  335. int r, g, b;
  336. color_conversion(L->base[o], cb->base[o], cr->base[o], &r, &g, &b);
  337. uint32_t c = 0xFF000000 | (r << 16) | (g << 8) | b;
  338. set_pixel((x * 8 + xx), (y * 8 + yy), c);
  339. }
  340. }
  341. }
  342. static void start_of_scan(FILE * f, int len) {
  343. TRACE("Reading image data");
  344. /* Skip header */
  345. fseek(f, len, SEEK_CUR);
  346. /* Initialize bit stream */
  347. struct stream _st = {0};
  348. _st.file = f;
  349. struct stream * st = &_st;
  350. int old_lum = 0;
  351. int old_crd = 0;
  352. int old_cbd = 0;
  353. for (int y = 0; y < sprite->height / 8 + !!(sprite->height & 0x7); ++y) {
  354. TRACE("Star row %d", y );
  355. for (int x = 0; x < sprite->width / 8 + !!(sprite->width & 0x7); ++x) {
  356. if (y >= 134) {
  357. TRACE("Start col %d", x);
  358. }
  359. /* Build matrices */
  360. struct idct matL, matCr, matCb;
  361. build_matrix(&matL, st, 0, quant[quant_mapping[0]], old_lum, &old_lum);
  362. build_matrix(&matCb, st, 1, quant[quant_mapping[1]], old_cbd, &old_cbd);
  363. build_matrix(&matCr, st, 1, quant[quant_mapping[2]], old_crd, &old_crd);
  364. if (y >= 134) {
  365. TRACE("Draw col %d", x);
  366. }
  367. draw_matrix(x, y, &matL, &matCb, &matCr);
  368. }
  369. }
  370. TRACE("Done.");
  371. }
  372. int load_sprite_jpg(sprite_t * tsprite, char * filename) {
  373. FILE * f = fopen(filename, "r");
  374. if (!f) {
  375. return 1;
  376. }
  377. sprite = tsprite;
  378. memset(huffman_tables, 0, sizeof(huffman_tables));
  379. if (premul[0][0][0][0] == 0.0) {
  380. for (int n = 0; n < 8; ++n) {
  381. for (int m = 0; m < 8; ++m) {
  382. for (int y = 0; y < 8; ++y) {
  383. for (int x = 0; x < 8; ++x) {
  384. premul[n][m][y][x] = cosines[n][x] * cosines[m][y];
  385. }
  386. }
  387. }
  388. }
  389. }
  390. while (1) {
  391. /* Read a header */
  392. uint16_t hdr;
  393. int r = fread(&hdr, 2, 1, f);
  394. if (r <= 0) {
  395. /* EOF */
  396. break;
  397. }
  398. /* These headers are stored big-endian */
  399. swap16(&hdr);
  400. if (hdr == 0xffd8) {
  401. /* No data */
  402. continue;
  403. } else if (hdr == 0xffd9) {
  404. /* End of file */
  405. break;
  406. } else {
  407. /* Regular sections with data start with a length */
  408. uint16_t len;
  409. fread(&len, 2, 1, f);
  410. swap16(&len);
  411. /* Subtract two because the length includes itself */
  412. len -= 2;
  413. if (hdr == 0xffdb) {
  414. define_quant_table(f, len);
  415. } else if (hdr == 0xffc0) {
  416. baseline_dct(f, len);
  417. } else if (hdr == 0xffc4) {
  418. define_huffman_table(f, len);
  419. } else if (hdr == 0xffda) {
  420. start_of_scan(f, len);
  421. /* End immediately after reading the data */
  422. break;
  423. } else {
  424. TRACE("Unknown header\n");
  425. fseek(f, len, SEEK_CUR);
  426. }
  427. }
  428. }
  429. fclose(f);
  430. return 0;
  431. }