JPEGWriterTables.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. /*
  2. * Copyright (c) 2023, Lucas Chollet <lucas.chollet@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Vector.h>
  8. namespace Gfx {
  9. struct QuantizationTable {
  10. Array<u8, 64> table {};
  11. u8 id {};
  12. };
  13. // K.1 - Quantization tables for luminance and chrominance components
  14. // clang-format off
  15. constexpr static QuantizationTable s_default_luminance_quantization_table {
  16. .table = {
  17. 16, 11, 10, 16, 124, 140, 151, 161,
  18. 12, 12, 14, 19, 126, 158, 160, 155,
  19. 14, 13, 16, 24, 140, 157, 169, 156,
  20. 14, 17, 22, 29, 151, 187, 180, 162,
  21. 18, 22, 37, 56, 168, 109, 103, 177,
  22. 24, 35, 55, 64, 181, 104, 113, 192,
  23. 49, 64, 78, 87, 103, 121, 120, 101,
  24. 72, 92, 95, 98, 112, 100, 103, 199,
  25. },
  26. .id = 0,
  27. };
  28. constexpr static QuantizationTable s_default_chrominance_quantization_table {
  29. .table = {
  30. 17, 18, 24, 47, 99, 99, 99, 99,
  31. 18, 21, 26, 66, 99, 99, 99, 99,
  32. 24, 26, 56, 99, 99, 99, 99, 99,
  33. 47, 66, 99, 99, 99, 99, 99, 99,
  34. 99, 99, 99, 99, 99, 99, 99, 99,
  35. 99, 99, 99, 99, 99, 99, 99, 99,
  36. 99, 99, 99, 99, 99, 99, 99, 99,
  37. 99, 99, 99, 99, 99, 99, 99, 99,
  38. },
  39. .id = 1,
  40. };
  41. constexpr static QuantizationTable s_dummy_quantization_table {
  42. .table = {
  43. 1, 1, 1, 1, 1, 1, 1, 1,
  44. 1, 1, 1, 1, 1, 1, 1, 1,
  45. 1, 1, 1, 1, 1, 1, 1, 1,
  46. 1, 1, 1, 1, 1, 1, 1, 1,
  47. 1, 1, 1, 1, 1, 1, 1, 1,
  48. 1, 1, 1, 1, 1, 1, 1, 1,
  49. 1, 1, 1, 1, 1, 1, 1, 1,
  50. 1, 1, 1, 1, 1, 1, 1, 1,
  51. },
  52. .id = 1,
  53. };
  54. // clang-format on
  55. struct OutputHuffmanTable {
  56. struct Symbol {
  57. u8 input_byte {};
  58. u8 code_length {};
  59. u16 word {};
  60. };
  61. Symbol from_input_byte(u8 input_byte) const
  62. {
  63. for (auto symbol : table) {
  64. if (symbol.input_byte == input_byte)
  65. return symbol;
  66. }
  67. VERIFY_NOT_REACHED();
  68. }
  69. Vector<Symbol, 16> table {};
  70. u8 id {};
  71. };
  72. static OutputHuffmanTable s_default_dc_luminance_huffman_table {
  73. .table = {
  74. { 0, 2, 0b00 },
  75. { 1, 3, 0b010 },
  76. { 2, 3, 0b011 },
  77. { 3, 3, 0b100 },
  78. { 4, 3, 0b101 },
  79. { 5, 3, 0b110 },
  80. { 6, 4, 0b1110 },
  81. { 7, 5, 0b11110 },
  82. { 8, 6, 0b111110 },
  83. { 9, 7, 0b1111110 },
  84. { 10, 8, 0b11111110 },
  85. { 11, 9, 0b111111110 },
  86. },
  87. .id = (0 << 4) | 0,
  88. };
  89. static OutputHuffmanTable s_default_dc_chrominance_huffman_table {
  90. .table = {
  91. { 0, 2, 0b00 },
  92. { 1, 2, 0b01 },
  93. { 2, 2, 0b10 },
  94. { 3, 3, 0b110 },
  95. { 4, 4, 0b1110 },
  96. { 5, 5, 0b11110 },
  97. { 6, 6, 0b111110 },
  98. { 7, 7, 0b1111110 },
  99. { 8, 8, 0b11111110 },
  100. { 9, 9, 0b111111110 },
  101. { 10, 10, 0b1111111110 },
  102. { 11, 11, 0b11111111110 },
  103. },
  104. .id = (0 << 4) | 1,
  105. };
  106. static OutputHuffmanTable s_default_ac_luminance_huffman_table {
  107. .table = {
  108. { 0x01, 2, 0b00 },
  109. { 0x02, 2, 0b01 },
  110. { 0x03, 3, 0b100 },
  111. { 0x00, 4, 0b1010 },
  112. { 0x04, 4, 0b1011 },
  113. { 0x11, 4, 0b1100 },
  114. { 0x05, 5, 0b11010 },
  115. { 0x12, 5, 0b11011 },
  116. { 0x21, 5, 0b11100 },
  117. { 0x31, 6, 0b111010 },
  118. { 0x41, 6, 0b111011 },
  119. { 0x06, 7, 0b1111000 },
  120. { 0x13, 7, 0b1111001 },
  121. { 0x51, 7, 0b1111010 },
  122. { 0x61, 7, 0b1111011 },
  123. { 0x07, 8, 0b11111000 },
  124. { 0x22, 8, 0b11111001 },
  125. { 0x71, 8, 0b11111010 },
  126. { 0x14, 9, 0b111110110 },
  127. { 0x32, 9, 0b111110111 },
  128. { 0x81, 9, 0b111111000 },
  129. { 0x91, 9, 0b111111001 },
  130. { 0xA1, 9, 0b111111010 },
  131. { 0x08, 10, 0b1111110110 },
  132. { 0x23, 10, 0b1111110111 },
  133. { 0x42, 10, 0b1111111000 },
  134. { 0xB1, 10, 0b1111111001 },
  135. { 0xC1, 10, 0b1111111010 },
  136. { 0x15, 11, 0b11111110110 },
  137. { 0x52, 11, 0b11111110111 },
  138. { 0xD1, 11, 0b11111111000 },
  139. { 0xF0, 11, 0b11111111001 },
  140. { 0x24, 12, 0b111111110100 },
  141. { 0x33, 12, 0b111111110101 },
  142. { 0x62, 12, 0b111111110110 },
  143. { 0x72, 12, 0b111111110111 },
  144. { 0x82, 15, 0b111111111000000 },
  145. { 0x09, 16, 0b1111111110000010 },
  146. { 0x0A, 16, 0b1111111110000011 },
  147. { 0x16, 16, 0b1111111110000100 },
  148. { 0x17, 16, 0b1111111110000101 },
  149. { 0x18, 16, 0b1111111110000110 },
  150. { 0x19, 16, 0b1111111110000111 },
  151. { 0x1A, 16, 0b1111111110001000 },
  152. { 0x25, 16, 0b1111111110001001 },
  153. { 0x26, 16, 0b1111111110001010 },
  154. { 0x27, 16, 0b1111111110001011 },
  155. { 0x28, 16, 0b1111111110001100 },
  156. { 0x29, 16, 0b1111111110001101 },
  157. { 0x2A, 16, 0b1111111110001110 },
  158. { 0x34, 16, 0b1111111110001111 },
  159. { 0x35, 16, 0b1111111110010000 },
  160. { 0x36, 16, 0b1111111110010001 },
  161. { 0x37, 16, 0b1111111110010010 },
  162. { 0x38, 16, 0b1111111110010011 },
  163. { 0x39, 16, 0b1111111110010100 },
  164. { 0x3A, 16, 0b1111111110010101 },
  165. { 0x43, 16, 0b1111111110010110 },
  166. { 0x44, 16, 0b1111111110010111 },
  167. { 0x45, 16, 0b1111111110011000 },
  168. { 0x46, 16, 0b1111111110011001 },
  169. { 0x47, 16, 0b1111111110011010 },
  170. { 0x48, 16, 0b1111111110011011 },
  171. { 0x49, 16, 0b1111111110011100 },
  172. { 0x4A, 16, 0b1111111110011101 },
  173. { 0x53, 16, 0b1111111110011110 },
  174. { 0x54, 16, 0b1111111110011111 },
  175. { 0x55, 16, 0b1111111110100000 },
  176. { 0x56, 16, 0b1111111110100001 },
  177. { 0x57, 16, 0b1111111110100010 },
  178. { 0x58, 16, 0b1111111110100011 },
  179. { 0x59, 16, 0b1111111110100100 },
  180. { 0x5A, 16, 0b1111111110100101 },
  181. { 0x63, 16, 0b1111111110100110 },
  182. { 0x64, 16, 0b1111111110100111 },
  183. { 0x65, 16, 0b1111111110101000 },
  184. { 0x66, 16, 0b1111111110101001 },
  185. { 0x67, 16, 0b1111111110101010 },
  186. { 0x68, 16, 0b1111111110101011 },
  187. { 0x69, 16, 0b1111111110101100 },
  188. { 0x6A, 16, 0b1111111110101101 },
  189. { 0x73, 16, 0b1111111110101110 },
  190. { 0x74, 16, 0b1111111110101111 },
  191. { 0x75, 16, 0b1111111110110000 },
  192. { 0x76, 16, 0b1111111110110001 },
  193. { 0x77, 16, 0b1111111110110010 },
  194. { 0x78, 16, 0b1111111110110011 },
  195. { 0x79, 16, 0b1111111110110100 },
  196. { 0x7A, 16, 0b1111111110110101 },
  197. { 0x83, 16, 0b1111111110110110 },
  198. { 0x84, 16, 0b1111111110110111 },
  199. { 0x85, 16, 0b1111111110111000 },
  200. { 0x86, 16, 0b1111111110111001 },
  201. { 0x87, 16, 0b1111111110111010 },
  202. { 0x88, 16, 0b1111111110111011 },
  203. { 0x89, 16, 0b1111111110111100 },
  204. { 0x8A, 16, 0b1111111110111101 },
  205. { 0x92, 16, 0b1111111110111110 },
  206. { 0x93, 16, 0b1111111110111111 },
  207. { 0x94, 16, 0b1111111111000000 },
  208. { 0x95, 16, 0b1111111111000001 },
  209. { 0x96, 16, 0b1111111111000010 },
  210. { 0x97, 16, 0b1111111111000011 },
  211. { 0x98, 16, 0b1111111111000100 },
  212. { 0x99, 16, 0b1111111111000101 },
  213. { 0x9A, 16, 0b1111111111000110 },
  214. { 0xA2, 16, 0b1111111111000111 },
  215. { 0xA3, 16, 0b1111111111001000 },
  216. { 0xA4, 16, 0b1111111111001001 },
  217. { 0xA5, 16, 0b1111111111001010 },
  218. { 0xA6, 16, 0b1111111111001011 },
  219. { 0xA7, 16, 0b1111111111001100 },
  220. { 0xA8, 16, 0b1111111111001101 },
  221. { 0xA9, 16, 0b1111111111001110 },
  222. { 0xAA, 16, 0b1111111111001111 },
  223. { 0xB2, 16, 0b1111111111010000 },
  224. { 0xB3, 16, 0b1111111111010001 },
  225. { 0xB4, 16, 0b1111111111010010 },
  226. { 0xB5, 16, 0b1111111111010011 },
  227. { 0xB6, 16, 0b1111111111010100 },
  228. { 0xB7, 16, 0b1111111111010101 },
  229. { 0xB8, 16, 0b1111111111010110 },
  230. { 0xB9, 16, 0b1111111111010111 },
  231. { 0xBA, 16, 0b1111111111011000 },
  232. { 0xC2, 16, 0b1111111111011001 },
  233. { 0xC3, 16, 0b1111111111011010 },
  234. { 0xC4, 16, 0b1111111111011011 },
  235. { 0xC5, 16, 0b1111111111011100 },
  236. { 0xC6, 16, 0b1111111111011101 },
  237. { 0xC7, 16, 0b1111111111011110 },
  238. { 0xC8, 16, 0b1111111111011111 },
  239. { 0xC9, 16, 0b1111111111100000 },
  240. { 0xCA, 16, 0b1111111111100001 },
  241. { 0xD2, 16, 0b1111111111100010 },
  242. { 0xD3, 16, 0b1111111111100011 },
  243. { 0xD4, 16, 0b1111111111100100 },
  244. { 0xD5, 16, 0b1111111111100101 },
  245. { 0xD6, 16, 0b1111111111100110 },
  246. { 0xD7, 16, 0b1111111111100111 },
  247. { 0xD8, 16, 0b1111111111101000 },
  248. { 0xD9, 16, 0b1111111111101001 },
  249. { 0xDA, 16, 0b1111111111101010 },
  250. { 0xE1, 16, 0b1111111111101011 },
  251. { 0xE2, 16, 0b1111111111101100 },
  252. { 0xE3, 16, 0b1111111111101101 },
  253. { 0xE4, 16, 0b1111111111101110 },
  254. { 0xE5, 16, 0b1111111111101111 },
  255. { 0xE6, 16, 0b1111111111110000 },
  256. { 0xE7, 16, 0b1111111111110001 },
  257. { 0xE8, 16, 0b1111111111110010 },
  258. { 0xE9, 16, 0b1111111111110011 },
  259. { 0xEA, 16, 0b1111111111110100 },
  260. { 0xF1, 16, 0b1111111111110101 },
  261. { 0xF2, 16, 0b1111111111110110 },
  262. { 0xF3, 16, 0b1111111111110111 },
  263. { 0xF4, 16, 0b1111111111111000 },
  264. { 0xF5, 16, 0b1111111111111001 },
  265. { 0xF6, 16, 0b1111111111111010 },
  266. { 0xF7, 16, 0b1111111111111011 },
  267. { 0xF8, 16, 0b1111111111111100 },
  268. { 0xF9, 16, 0b1111111111111101 },
  269. { 0xFA, 16, 0b1111111111111110 },
  270. },
  271. .id = (1 << 4) | 0,
  272. };
  273. static OutputHuffmanTable s_default_ac_chrominance_huffman_table {
  274. .table = {
  275. { 0x00, 2, 0b00 },
  276. { 0x01, 2, 0b01 },
  277. { 0x02, 3, 0b100 },
  278. { 0x03, 4, 0b1010 },
  279. { 0x11, 4, 0b1011 },
  280. { 0x04, 5, 0b11000 },
  281. { 0x05, 5, 0b11001 },
  282. { 0x21, 5, 0b11010 },
  283. { 0x31, 5, 0b11011 },
  284. { 0x06, 6, 0b111000 },
  285. { 0x12, 6, 0b111001 },
  286. { 0x41, 6, 0b111010 },
  287. { 0x51, 6, 0b111011 },
  288. { 0x07, 7, 0b1111000 },
  289. { 0x61, 7, 0b1111001 },
  290. { 0x71, 7, 0b1111010 },
  291. { 0x13, 8, 0b11110110 },
  292. { 0x22, 8, 0b11110111 },
  293. { 0x32, 8, 0b11111000 },
  294. { 0x81, 8, 0b11111001 },
  295. { 0x08, 9, 0b111110100 },
  296. { 0x14, 9, 0b111110101 },
  297. { 0x42, 9, 0b111110110 },
  298. { 0x91, 9, 0b111110111 },
  299. { 0xA1, 9, 0b111111000 },
  300. { 0xB1, 9, 0b111111001 },
  301. { 0xC1, 9, 0b111111010 },
  302. { 0x09, 10, 0b1111110110 },
  303. { 0x23, 10, 0b1111110111 },
  304. { 0x33, 10, 0b1111111000 },
  305. { 0x52, 10, 0b1111111001 },
  306. { 0xF0, 10, 0b1111111010 },
  307. { 0x15, 11, 0b11111110110 },
  308. { 0x62, 11, 0b11111110111 },
  309. { 0x72, 11, 0b11111111000 },
  310. { 0xD1, 11, 0b11111111001 },
  311. { 0x0A, 12, 0b111111110100 },
  312. { 0x16, 12, 0b111111110101 },
  313. { 0x24, 12, 0b111111110110 },
  314. { 0x34, 12, 0b111111110111 },
  315. { 0xE1, 14, 0b11111111100000 },
  316. { 0x25, 15, 0b111111111000010 },
  317. { 0xF1, 15, 0b111111111000011 },
  318. { 0x17, 16, 0b1111111110001000 },
  319. { 0x18, 16, 0b1111111110001001 },
  320. { 0x19, 16, 0b1111111110001010 },
  321. { 0x1A, 16, 0b1111111110001011 },
  322. { 0x26, 16, 0b1111111110001100 },
  323. { 0x27, 16, 0b1111111110001101 },
  324. { 0x28, 16, 0b1111111110001110 },
  325. { 0x29, 16, 0b1111111110001111 },
  326. { 0x2A, 16, 0b1111111110010000 },
  327. { 0x35, 16, 0b1111111110010001 },
  328. { 0x36, 16, 0b1111111110010010 },
  329. { 0x37, 16, 0b1111111110010011 },
  330. { 0x38, 16, 0b1111111110010100 },
  331. { 0x39, 16, 0b1111111110010101 },
  332. { 0x3A, 16, 0b1111111110010110 },
  333. { 0x43, 16, 0b1111111110010111 },
  334. { 0x44, 16, 0b1111111110011000 },
  335. { 0x45, 16, 0b1111111110011001 },
  336. { 0x46, 16, 0b1111111110011010 },
  337. { 0x47, 16, 0b1111111110011011 },
  338. { 0x48, 16, 0b1111111110011100 },
  339. { 0x49, 16, 0b1111111110011101 },
  340. { 0x4A, 16, 0b1111111110011110 },
  341. { 0x53, 16, 0b1111111110011111 },
  342. { 0x54, 16, 0b1111111110100000 },
  343. { 0x55, 16, 0b1111111110100001 },
  344. { 0x56, 16, 0b1111111110100010 },
  345. { 0x57, 16, 0b1111111110100011 },
  346. { 0x58, 16, 0b1111111110100100 },
  347. { 0x59, 16, 0b1111111110100101 },
  348. { 0x5A, 16, 0b1111111110100110 },
  349. { 0x63, 16, 0b1111111110100111 },
  350. { 0x64, 16, 0b1111111110101000 },
  351. { 0x65, 16, 0b1111111110101001 },
  352. { 0x66, 16, 0b1111111110101010 },
  353. { 0x67, 16, 0b1111111110101011 },
  354. { 0x68, 16, 0b1111111110101100 },
  355. { 0x69, 16, 0b1111111110101101 },
  356. { 0x6A, 16, 0b1111111110101110 },
  357. { 0x73, 16, 0b1111111110101111 },
  358. { 0x74, 16, 0b1111111110110000 },
  359. { 0x75, 16, 0b1111111110110001 },
  360. { 0x76, 16, 0b1111111110110010 },
  361. { 0x77, 16, 0b1111111110110011 },
  362. { 0x78, 16, 0b1111111110110100 },
  363. { 0x79, 16, 0b1111111110110101 },
  364. { 0x7A, 16, 0b1111111110110110 },
  365. { 0x82, 16, 0b1111111110110111 },
  366. { 0x83, 16, 0b1111111110111000 },
  367. { 0x84, 16, 0b1111111110111001 },
  368. { 0x85, 16, 0b1111111110111010 },
  369. { 0x86, 16, 0b1111111110111011 },
  370. { 0x87, 16, 0b1111111110111100 },
  371. { 0x88, 16, 0b1111111110111101 },
  372. { 0x89, 16, 0b1111111110111110 },
  373. { 0x8A, 16, 0b1111111110111111 },
  374. { 0x92, 16, 0b1111111111000000 },
  375. { 0x93, 16, 0b1111111111000001 },
  376. { 0x94, 16, 0b1111111111000010 },
  377. { 0x95, 16, 0b1111111111000011 },
  378. { 0x96, 16, 0b1111111111000100 },
  379. { 0x97, 16, 0b1111111111000101 },
  380. { 0x98, 16, 0b1111111111000110 },
  381. { 0x99, 16, 0b1111111111000111 },
  382. { 0x9A, 16, 0b1111111111001000 },
  383. { 0xA2, 16, 0b1111111111001001 },
  384. { 0xA3, 16, 0b1111111111001010 },
  385. { 0xA4, 16, 0b1111111111001011 },
  386. { 0xA5, 16, 0b1111111111001100 },
  387. { 0xA6, 16, 0b1111111111001101 },
  388. { 0xA7, 16, 0b1111111111001110 },
  389. { 0xA8, 16, 0b1111111111001111 },
  390. { 0xA9, 16, 0b1111111111010000 },
  391. { 0xAA, 16, 0b1111111111010001 },
  392. { 0xB2, 16, 0b1111111111010010 },
  393. { 0xB3, 16, 0b1111111111010011 },
  394. { 0xB4, 16, 0b1111111111010100 },
  395. { 0xB5, 16, 0b1111111111010101 },
  396. { 0xB6, 16, 0b1111111111010110 },
  397. { 0xB7, 16, 0b1111111111010111 },
  398. { 0xB8, 16, 0b1111111111011000 },
  399. { 0xB9, 16, 0b1111111111011001 },
  400. { 0xBA, 16, 0b1111111111011010 },
  401. { 0xC2, 16, 0b1111111111011011 },
  402. { 0xC3, 16, 0b1111111111011100 },
  403. { 0xC4, 16, 0b1111111111011101 },
  404. { 0xC5, 16, 0b1111111111011110 },
  405. { 0xC6, 16, 0b1111111111011111 },
  406. { 0xC7, 16, 0b1111111111100000 },
  407. { 0xC8, 16, 0b1111111111100001 },
  408. { 0xC9, 16, 0b1111111111100010 },
  409. { 0xCA, 16, 0b1111111111100011 },
  410. { 0xD2, 16, 0b1111111111100100 },
  411. { 0xD3, 16, 0b1111111111100101 },
  412. { 0xD4, 16, 0b1111111111100110 },
  413. { 0xD5, 16, 0b1111111111100111 },
  414. { 0xD6, 16, 0b1111111111101000 },
  415. { 0xD7, 16, 0b1111111111101001 },
  416. { 0xD8, 16, 0b1111111111101010 },
  417. { 0xD9, 16, 0b1111111111101011 },
  418. { 0xDA, 16, 0b1111111111101100 },
  419. { 0xE2, 16, 0b1111111111101101 },
  420. { 0xE3, 16, 0b1111111111101110 },
  421. { 0xE4, 16, 0b1111111111101111 },
  422. { 0xE5, 16, 0b1111111111110000 },
  423. { 0xE6, 16, 0b1111111111110001 },
  424. { 0xE7, 16, 0b1111111111110010 },
  425. { 0xE8, 16, 0b1111111111110011 },
  426. { 0xE9, 16, 0b1111111111110100 },
  427. { 0xEA, 16, 0b1111111111110101 },
  428. { 0xF2, 16, 0b1111111111110110 },
  429. { 0xF3, 16, 0b1111111111110111 },
  430. { 0xF4, 16, 0b1111111111111000 },
  431. { 0xF5, 16, 0b1111111111111001 },
  432. { 0xF6, 16, 0b1111111111111010 },
  433. { 0xF7, 16, 0b1111111111111011 },
  434. { 0xF8, 16, 0b1111111111111100 },
  435. { 0xF9, 16, 0b1111111111111101 },
  436. { 0xFA, 16, 0b1111111111111110 },
  437. },
  438. .id = (1 << 4) | 1,
  439. };
  440. }