mirror of
git://nv-tegra.nvidia.com/tegra/v4l2-src/v4l2_libs.git
synced 2025-12-22 09:21:28 +03:00
f07563fa1628a75c578152387638b1f217f730be - libv4lconvert/Makefile 6ac3c887c56c7d4345499cb5b7bfac9579a57d16 - libv4lconvert/cpia1.c 2d385802ec3690e78a961ce95431e98eb3f5fc6a - libv4lconvert/rgbyuv.c 43843cbdb81f3efee5873f5ed25ae1eb7745a9e5 - libv4lconvert/libv4lconvert-priv.h 002783c808dc565478c18bd27373792028264bb6 - libv4lconvert/ov518-decomp.c 4d49e6e897046e66e41c3563fec2eb2562abf813 - libv4lconvert/jpeg_memsrcdest.c a38fdb4c79518e972678745c93cd62881d72972b - libv4lconvert/Makefile.dGPU e9f783fb933606224252dfd3093afa36490f6f4c - libv4lconvert/Makefile.in 52900601a24ee9ffea87ca7fe6651e912e20235e - libv4lconvert/libv4lsyscall-priv.h d37f854500cbd759ad93ae89c6aa75c00b000931 - libv4lconvert/bayer.c 2cd1b994bb7999d0c08c19b1a2efd11707250852 - libv4lconvert/helper.c adac14b8826d05ddab33d595a803e92eaf84b797 - libv4lconvert/Makefile.am 6e806290f6e426c881322d362f189fa7b9e2f917 - libv4lconvert/sn9c10x.c ba44b6ac00a643e6df484f3172022e1b2628c0cc - libv4lconvert/jpgl.c fa06343de31dcf6d3d5862cc278396272fa838c4 - libv4lconvert/se401.c 4bd081bf25b63f5463d582ef36f77ba5e3711d0d - libv4lconvert/sq905c.c 940250beb5898bf254e7cd1ef9d7950a8db10af6 - libv4lconvert/mr97310a.c 5e177c3a7c157c25c4afcae031e79830237510f6 - libv4lconvert/libv4lconvert.c 1f362080c319355070cf409cfccf28d8c68d024e - libv4lconvert/sn9c2028-decomp.c 703ce22dc98d834490c7aa23ae73b9113e386221 - libv4lconvert/sn9c20x.c 018e503969b2e06a0ea639fc08f03a7476cc15b5 - libv4lconvert/jpeg_memsrcdest.h fb3344cfa8df97688332ee4fd3b17968437e8ad5 - libv4lconvert/helper-funcs.h d378cbdd377027e7528af47362a94ccb1ae15da3 - libv4lconvert/libv4lconvert.export 61710972d4e9bfcd00490c563d1bb5bde5480c9e - libv4lconvert/tinyjpeg.c 231571db9f8caa6fdc68138102029127a6b93812 - libv4lconvert/crop.c d62448a06539ecf6e3daae7faa299b6da8878054 - libv4lconvert/pac207.c 72b65c9f0f3c87dcae86a2afbea65a76f2c6bafd - libv4lconvert/tinyjpeg-internal.h a016f896e0e9f0cd8af7447b52651ed14c5a5b29 - libv4lconvert/jpeg.c 608a4c341a5df9daea647fbddc415cdaf27b0482 - libv4lconvert/spca561-decompress.c b03b32eae024bf59b6ceaf6b6d342383cd0b0673 - libv4lconvert/jl2005bcd.c 803c4d0b9364050eda163452b8792e62e221ab6d - libv4lconvert/tinyjpeg.h 2df34af8f9d747fb0e5c7c71954c788aff1c483f - libv4lconvert/stv0680.c 3e8e6c1fb85e3c4b58c4e9b2b0a223ddc793edcb - libv4lconvert/libv4lconvert.pc.in 02aa2e7d12b72fe4ce79cdf4009da61f35091e94 - libv4lconvert/flip.c 05038ef9efab175322a12d3d6620dba6298aa2a9 - libv4lconvert/spca501.c b2c19c2eac71d39d3fb883cdc159a69c2afa8fd6 - libv4lconvert/ov511-decomp.c 1d9c446cd8a232da87bd79acebc93e018ec72499 - libv4lconvert/jidctflt.c ed215eca170d07a6838be3796aad933adf89ece2 - libv4lconvert/hm12.c 193e9d2c997e21ce8ca02f25050fb8d2d62b6bfd - libv4lconvert/processing/autogain.c c894d4a9b9e0f95be9e7bade4f7f734ae0c6996c - libv4lconvert/processing/libv4lprocessing.c 4158e9c3d21cf0a064b99bdf8571df4f3ba6d5bb - libv4lconvert/processing/whitebalance.c be34baf0d2ce1374c841494ba27ccc352c444e98 - libv4lconvert/processing/gamma.c b48edcb4036ee5f4e77e9cb49dd1b52b1e7f2427 - libv4lconvert/processing/libv4lprocessing.h 967d27c0e09849338a69dc4b5647d1824f2cd2fb - libv4lconvert/processing/libv4lprocessing-priv.h 9f382ff1f2895b926f3596e0a8ae7637b5e6a2ac - libv4lconvert/control/libv4lcontrol.c 8c523bd3838004a4fa00430a38cbc6dbaa47286f - libv4lconvert/control/libv4lcontrol.h 4ce5e891af7857a3504d1350ef13015997dde62a - libv4lconvert/control/libv4lcontrol-priv.h bda0c1296aad2b3b178a76f38e26c20ce3b81233 - include/libv4l1.h a95818658d95c1602f2422e5f1fb54b9ca70536e - include/libv4l2rds.h 2d1932763a064ef1176450b1bb4dd242aa3c77bb - include/libv4lconvert.h 3517bc15e30852ad01ad9966ec7111a16a2263df - include/libv4l2.h 944cd9bc32420e73da3a7d3cb1d0ce707263c9f0 - include/libv4l1-videodev.h 7d9d199f4e6f4ba6f0d669ee5decd74355507137 - include/libv4l-plugin.h cfeaf0c16571e0c64bce50bcb8a6cd8d8c976187 - include/config.h d7d4fd219e36edadc17837bff78eb8323e2a115e - include/libdvbv5/libdvb-version.h 33071176eda60242f39927e572ac6b1c1bab32e2 - include/libdvbv5/desc_event_extended.h 29c2cd2554e4f4285ab8709e6eace38046d8ecdc - include/libdvbv5/desc_t2_delivery.h b42819db457bc6a23324faf259c0db1104741d99 - include/libdvbv5/dvb-scan.h bae10c2fa28bb522e9fc0bb5e4b0128ab6f90e65 - include/libdvbv5/desc_partial_reception.h f797ddac8e1adc6b29750f076df0f3a23cf630eb - include/libdvbv5/dvb-v5-std.h 48079dcae511070a8eeb55b004bd8ac06735ecc7 - include/libdvbv5/desc_ca.h f4eb8b615b7c5a245c76e3f448e6cd848d8cf765 - include/libdvbv5/desc_cable_delivery.h 170a50b570691975e0ff22faffeb0131fc47c7c8 - include/libdvbv5/desc_logical_channel.h c8f11e89456fc078c607d424e887babe72cd3684 - include/libdvbv5/nit.h d39a24d0d0a0fbe732881dd2734b10d842d88de9 - include/libdvbv5/header.h badc03677ddbcfa1d1188ddaaa4c272fccfe4a21 - include/libdvbv5/desc_atsc_service_location.h d3bad046037cad4a95778555021a1a1a6b3040d9 - include/libdvbv5/cat.h a614739513f62affb1059df81c064203d9fe2fcd - include/libdvbv5/desc_ca_identifier.h 6d70f699eb912c974dc06a19f9bdcb7dd0c27932 - include/libdvbv5/desc_service.h 0eda1161b34ca39b8528bc53d05fb0fc7d457f80 - include/libdvbv5/desc_frequency_list.h 22f6b663d50de467539201ecfdb363e9252c88bd - include/libdvbv5/atsc_eit.h 1c1292f060664abf6c12273a41b2bf6f704dd19b - include/libdvbv5/desc_sat.h 22de6de5e65530aa1ab38a2373db128e81983a4c - include/libdvbv5/desc_network_name.h 91178a5945e63c81051b57b7b2842139947a3b39 - include/libdvbv5/desc_extension.h 9ca776ad159cf84b2f68101bf279472741829047 - include/libdvbv5/descriptors.h fa7e8d5e996310e1dd47d5467780d533c8a93ad8 - include/libdvbv5/dvb-dev.h fed6115825c5b23e1e31ff80aab997f0a7b6c3fc - include/libdvbv5/sdt.h 4b892acd2ce77c060b50cf67f5faf9dc9b76edbb - include/libdvbv5/dvb-frontend.h 8b9f9e00f7bcdce58aef1d8d7234567af82e49b8 - include/libdvbv5/dvb-file.h b8a077b8e3c6e337223fc37685d217a81df112f1 - include/libdvbv5/dvb-demux.h 01a0afbe1a4f41cf58f9ce47d65b31e3df7c8680 - include/libdvbv5/pat.h 4a49c8b46947be16356d6355aa36d72d7baa946c - include/libdvbv5/vct.h c83200debc98ff8fa82030d36371a2caa230281a - include/libdvbv5/desc_language.h 21cea15c5d4faff2726f18bdf5b83e2210d472c4 - include/libdvbv5/mpeg_pes.h 825f75350da9fb148acc7d36af513da977105169 - include/libdvbv5/desc_isdbt_delivery.h 8f60bf43907b1eac3c1c2f031cf68a9bdebb3662 - include/libdvbv5/desc_ts_info.h 89cbb75f3e0952e4dfb145fdea776b45e05b7e76 - include/libdvbv5/desc_hierarchy.h 5c80a7ee23d1da2c91f60e79f7292248694b4f65 - include/libdvbv5/crc32.h 93b7b27ccc89e1ad4279eb12560e1dfc3d2ff1eb - include/libdvbv5/dvb-fe.h aeeb75989de4b2ecafa1b2fc5ed30787999eec1b - include/libdvbv5/mpeg_es.h dc684983365ffef353993faad0b105bcb87f4218 - include/libdvbv5/desc_event_short.h 5e3be50d1292109d59c80f920ba1b7a4bcbbdf56 - include/libdvbv5/eit.h f95a0206952db4cce561455accad66a37f9a4104 - include/libdvbv5/mgt.h 88f8c78bbaf22b345e2ccb68e9b787e649dac2c1 - include/libdvbv5/libdvb-version.h.in 74a66644980a66adeba21ecc40ebefa2b4480e25 - include/libdvbv5/pmt.h 7671f125c6f61eef85f55eb314097435b3772431 - include/libdvbv5/dvb-sat.h 26fd40a10548cdb9bd4aafdda4486f9d39fd5c9e - include/libdvbv5/countries.h 65db3beaf2ec19a43a870b2759e6aecb15a95c7b - include/libdvbv5/atsc_header.h 149f7eb3c71b8f65127d3c4f2143080b115697e5 - include/libdvbv5/desc_terrestrial_delivery.h 708af2b77b2c94ee9cf593b31e20471c80ea556b - include/libdvbv5/mpeg_ts.h ba205468e43ca16edf1ebec59dce9822044c1064 - include/libdvbv5/desc_registration_id.h e70b24d8d1f3a248735c2d724d3b92c49b7aaba5 - include/libdvbv5/dvb-log.h 2d0557eadd4cff02ab52e26778d35b6c34f09158 - libv4l2/libv4l2-priv.h 487af43db163be6d3604371b9a504c1df2a9bf6c - libv4l2/v4l2-plugin-android.c 0ac38b46fa1659db4c05660205f212389295e7ff - libv4l2/Makefile 8ac3789333a6cd18e7f35d3b66a8a4d0293feb78 - libv4l2/Makefile.dGPU fdd6e5e27aa8b41d5da77cb3b9be3fc3b8a44763 - libv4l2/libv4l2.export 1d37e5ea9231e7e0eea7d1a02938c6d1ae8ba791 - libv4l2/Makefile.in 650b8919b8e10f871be161dc5056fbe30618282c - libv4l2/v4l2-plugin.c d4c7daee644a35244ac8a5e1009a3aeb1d4fd3da - libv4l2/Makefile.am 87856c7113d150dceb254b5d548f942e7fcaf8f1 - libv4l2/libv4l2.c d11ec5b8ce8390a72fd61457d7b8667378311191 - libv4l2/log.c cbcee4426c19c168c6f49d04af3a0b2e30c0b681 - libv4l2/libv4l2.pc.in 55bb16d05817a3ecf076174175b2ca5b56e729d8 - libv4l2/v4l2convert.c Change-Id: I4133a070aa0ca5235776128e56699fed86e8522e
1483 lines
46 KiB
C
1483 lines
46 KiB
C
/* We would like to embed this inside libv4l, but we cannot as I've failed
|
|
to contact Mark W. McClelland to get permission to relicense this,
|
|
so this lives in an external (GPL licensed) helper */
|
|
|
|
/* OV518 Decompression Support Module (No-MMX version)
|
|
*
|
|
* Copyright (c) 2002-2003 Mark W. McClelland. All rights reserved.
|
|
* http://alpha.dyndns.org/ov511/
|
|
*
|
|
* Fast integer iDCT by Yuri van Oers <yvanoers AT xs4all.nl>
|
|
* Original OV511 decompression code Copyright 1998-2000 OmniVision Technologies
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; version 2 of the License.
|
|
*/
|
|
|
|
#include <limits.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include "helper-funcs.h"
|
|
|
|
/******************************************************************************
|
|
* Compile-time Options
|
|
******************************************************************************/
|
|
|
|
/* Defining APPROXIMATE_MUL_BY_SHIFT increases performance by approximation
|
|
* the multiplications by shifts. I think there's no change in the
|
|
* calculated picture, but I'm not sure, so the choice is still in here. */
|
|
#undef APPROXIMATE_MUL_BY_SHIFT
|
|
|
|
/******************************************************************************
|
|
* Local Data Types
|
|
******************************************************************************/
|
|
|
|
/* Make sure this remains naturally aligned and 2^n bytes in size */
|
|
struct tree_node {
|
|
short left; /* Pointer to left child node */
|
|
short right; /* Pointer to right child node */
|
|
signed char depth; /* Depth (starting at 1) if leaf, else -1 */
|
|
signed char coeffbits; /* Size of coefficient data, or zero if none */
|
|
signed char skip; /* Number of zero coefficients. Unused w/ DC */
|
|
char padding; /* Pad out to 8 bytes */
|
|
};
|
|
|
|
struct comp_info {
|
|
int bytes; /* Number of processed input bytes */
|
|
int bits; /* Number of unprocessed input bits */
|
|
int rawLen; /* Total number of bytes in input buffer */
|
|
unsigned char *qt; /* Current quantization table */
|
|
};
|
|
|
|
/******************************************************************************
|
|
* Constant Data Definitions
|
|
******************************************************************************/
|
|
|
|
/* Zig-Zag Table */
|
|
static const unsigned char ZigZag518[] = {
|
|
0x00, 0x02, 0x03, 0x09,
|
|
0x01, 0x04, 0x08, 0x0a,
|
|
0x05, 0x07, 0x0b, 0x11,
|
|
0x06, 0x0c, 0x10, 0x12,
|
|
0x0d, 0x0f, 0x13, 0x19,
|
|
0x0e, 0x14, 0x18, 0x1a,
|
|
0x15, 0x17, 0x1b, 0x1e,
|
|
0x16, 0x1c, 0x1d, 0x1f
|
|
};
|
|
|
|
/* Huffman trees */
|
|
|
|
static const struct tree_node treeYAC[] = {
|
|
{ 1, 4, -1, 0, -1}, { 2, 3, -1, 0, -1},
|
|
{ -1, -1, 2, 1, 0}, { -1, -1, 2, 2, 0},
|
|
{ 5, 9, -1, 0, -1}, { 6, 7, -1, 0, -1},
|
|
{ -1, -1, 3, 3, 0}, {323, 8, -1, 0, -1},
|
|
{ -1, -1, 4, 4, 0}, { 10, 13, -1, 0, -1},
|
|
{ 38, 11, -1, 0, -1}, { 12, 39, -1, 0, -1},
|
|
{ -1, -1, 5, 5, 0}, { 59, 14, -1, 0, -1},
|
|
{ 15, 18, -1, 0, -1}, { 16, 113, -1, 0, -1},
|
|
{ 17, 40, -1, 0, -1}, { -1, -1, 7, 6, 0},
|
|
{ 19, 22, -1, 0, -1}, { 20, 41, -1, 0, -1},
|
|
{ 21, 61, -1, 0, -1}, { -1, -1, 8, 7, 0},
|
|
{ 23, 27, -1, 0, -1}, {169, 24, -1, 0, -1},
|
|
{208, 25, -1, 0, -1}, { 26, 62, -1, 0, -1},
|
|
{ -1, -1, 10, 8, 0}, { 44, 28, -1, 0, -1},
|
|
{ 63, 29, -1, 0, -1}, { 30, 191, -1, 0, -1},
|
|
{ 31, 119, -1, 0, -1}, { 32, 82, -1, 0, -1},
|
|
{ 33, 55, -1, 0, -1}, { 34, 48, -1, 0, -1},
|
|
{171, 35, -1, 0, -1}, { 36, 37, -1, 0, -1},
|
|
{ -1, -1, 16, 9, 0}, { -1, -1, 16, 10, 0},
|
|
{ -1, -1, 4, 1, 1}, { -1, -1, 5, 2, 1},
|
|
{ -1, -1, 7, 3, 1}, {151, 42, -1, 0, -1},
|
|
{ 43, 79, -1, 0, -1}, { -1, -1, 9, 4, 1},
|
|
{ 96, 45, -1, 0, -1}, {246, 46, -1, 0, -1},
|
|
{ 47, 115, -1, 0, -1}, { -1, -1, 11, 5, 1},
|
|
{ 49, 52, -1, 0, -1}, { 50, 51, -1, 0, -1},
|
|
{ -1, -1, 16, 6, 1}, { -1, -1, 16, 7, 1},
|
|
{ 53, 54, -1, 0, -1}, { -1, -1, 16, 8, 1},
|
|
{ -1, -1, 16, 9, 1}, { 56, 71, -1, 0, -1},
|
|
{ 57, 68, -1, 0, -1}, { 58, 67, -1, 0, -1},
|
|
{ -1, -1, 16, 10, 1}, { 60, 77, -1, 0, -1},
|
|
{ -1, -1, 5, 1, 2}, { -1, -1, 8, 2, 2},
|
|
{ -1, -1, 10, 3, 2}, {265, 64, -1, 0, -1},
|
|
{ 65, 134, -1, 0, -1}, { 66, 80, -1, 0, -1},
|
|
{ -1, -1, 12, 4, 2}, { -1, -1, 16, 5, 2},
|
|
{ 69, 70, -1, 0, -1}, { -1, -1, 16, 6, 2},
|
|
{ -1, -1, 16, 7, 2}, { 72, 75, -1, 0, -1},
|
|
{ 73, 74, -1, 0, -1}, { -1, -1, 16, 8, 2},
|
|
{ -1, -1, 16, 9, 2}, { 76, 81, -1, 0, -1},
|
|
{ -1, -1, 16, 10, 2}, { 78, 95, -1, 0, -1},
|
|
{ -1, -1, 6, 1, 3}, { -1, -1, 9, 2, 3},
|
|
{ -1, -1, 12, 3, 3}, { -1, -1, 16, 4, 3},
|
|
{ 83, 101, -1, 0, -1}, { 84, 91, -1, 0, -1},
|
|
{ 85, 88, -1, 0, -1}, { 86, 87, -1, 0, -1},
|
|
{ -1, -1, 16, 5, 3}, { -1, -1, 16, 6, 3},
|
|
{ 89, 90, -1, 0, -1}, { -1, -1, 16, 7, 3},
|
|
{ -1, -1, 16, 8, 3}, { 92, 98, -1, 0, -1},
|
|
{ 93, 94, -1, 0, -1}, { -1, -1, 16, 9, 3},
|
|
{ -1, -1, 16, 10, 3}, { -1, -1, 6, 1, 4},
|
|
{ 97, 225, -1, 0, -1}, { -1, -1, 10, 2, 4},
|
|
{ 99, 100, -1, 0, -1}, { -1, -1, 16, 3, 4},
|
|
{ -1, -1, 16, 4, 4}, {102, 109, -1, 0, -1},
|
|
{103, 106, -1, 0, -1}, {104, 105, -1, 0, -1},
|
|
{ -1, -1, 16, 5, 4}, { -1, -1, 16, 6, 4},
|
|
{107, 108, -1, 0, -1}, { -1, -1, 16, 7, 4},
|
|
{ -1, -1, 16, 8, 4}, {110, 116, -1, 0, -1},
|
|
{111, 112, -1, 0, -1}, { -1, -1, 16, 9, 4},
|
|
{ -1, -1, 16, 10, 4}, {114, 133, -1, 0, -1},
|
|
{ -1, -1, 7, 1, 5}, { -1, -1, 11, 2, 5},
|
|
{117, 118, -1, 0, -1}, { -1, -1, 16, 3, 5},
|
|
{ -1, -1, 16, 4, 5}, {120, 156, -1, 0, -1},
|
|
{121, 139, -1, 0, -1}, {122, 129, -1, 0, -1},
|
|
{123, 126, -1, 0, -1}, {124, 125, -1, 0, -1},
|
|
{ -1, -1, 16, 5, 5}, { -1, -1, 16, 6, 5},
|
|
{127, 128, -1, 0, -1}, { -1, -1, 16, 7, 5},
|
|
{ -1, -1, 16, 8, 5}, {130, 136, -1, 0, -1},
|
|
{131, 132, -1, 0, -1}, { -1, -1, 16, 9, 5},
|
|
{ -1, -1, 16, 10, 5}, { -1, -1, 7, 1, 6},
|
|
{135, 152, -1, 0, -1}, { -1, -1, 12, 2, 6},
|
|
{137, 138, -1, 0, -1}, { -1, -1, 16, 3, 6},
|
|
{ -1, -1, 16, 4, 6}, {140, 147, -1, 0, -1},
|
|
{141, 144, -1, 0, -1}, {142, 143, -1, 0, -1},
|
|
{ -1, -1, 16, 5, 6}, { -1, -1, 16, 6, 6},
|
|
{145, 146, -1, 0, -1}, { -1, -1, 16, 7, 6},
|
|
{ -1, -1, 16, 8, 6}, {148, 153, -1, 0, -1},
|
|
{149, 150, -1, 0, -1}, { -1, -1, 16, 9, 6},
|
|
{ -1, -1, 16, 10, 6}, { -1, -1, 8, 1, 7},
|
|
{ -1, -1, 12, 2, 7}, {154, 155, -1, 0, -1},
|
|
{ -1, -1, 16, 3, 7}, { -1, -1, 16, 4, 7},
|
|
{157, 175, -1, 0, -1}, {158, 165, -1, 0, -1},
|
|
{159, 162, -1, 0, -1}, {160, 161, -1, 0, -1},
|
|
{ -1, -1, 16, 5, 7}, { -1, -1, 16, 6, 7},
|
|
{163, 164, -1, 0, -1}, { -1, -1, 16, 7, 7},
|
|
{ -1, -1, 16, 8, 7}, {166, 172, -1, 0, -1},
|
|
{167, 168, -1, 0, -1}, { -1, -1, 16, 9, 7},
|
|
{ -1, -1, 16, 10, 7}, {170, 187, -1, 0, -1},
|
|
{ -1, -1, 9, 1, 8}, { -1, -1, 15, 2, 8},
|
|
{173, 174, -1, 0, -1}, { -1, -1, 16, 3, 8},
|
|
{ -1, -1, 16, 4, 8}, {176, 183, -1, 0, -1},
|
|
{177, 180, -1, 0, -1}, {178, 179, -1, 0, -1},
|
|
{ -1, -1, 16, 5, 8}, { -1, -1, 16, 6, 8},
|
|
{181, 182, -1, 0, -1}, { -1, -1, 16, 7, 8},
|
|
{ -1, -1, 16, 8, 8}, {184, 188, -1, 0, -1},
|
|
{185, 186, -1, 0, -1}, { -1, -1, 16, 9, 8},
|
|
{ -1, -1, 16, 10, 8}, { -1, -1, 9, 1, 9},
|
|
{189, 190, -1, 0, -1}, { -1, -1, 16, 2, 9},
|
|
{ -1, -1, 16, 3, 9}, {192, 258, -1, 0, -1},
|
|
{193, 226, -1, 0, -1}, {194, 210, -1, 0, -1},
|
|
{195, 202, -1, 0, -1}, {196, 199, -1, 0, -1},
|
|
{197, 198, -1, 0, -1}, { -1, -1, 16, 4, 9},
|
|
{ -1, -1, 16, 5, 9}, {200, 201, -1, 0, -1},
|
|
{ -1, -1, 16, 6, 9}, { -1, -1, 16, 7, 9},
|
|
{203, 206, -1, 0, -1}, {204, 205, -1, 0, -1},
|
|
{ -1, -1, 16, 8, 9}, { -1, -1, 16, 9, 9},
|
|
{207, 209, -1, 0, -1}, { -1, -1, 16, 10, 9},
|
|
{ -1, -1, 9, 1, 10}, { -1, -1, 16, 2, 10},
|
|
{211, 218, -1, 0, -1}, {212, 215, -1, 0, -1},
|
|
{213, 214, -1, 0, -1}, { -1, -1, 16, 3, 10},
|
|
{ -1, -1, 16, 4, 10}, {216, 217, -1, 0, -1},
|
|
{ -1, -1, 16, 5, 10}, { -1, -1, 16, 6, 10},
|
|
{219, 222, -1, 0, -1}, {220, 221, -1, 0, -1},
|
|
{ -1, -1, 16, 7, 10}, { -1, -1, 16, 8, 10},
|
|
{223, 224, -1, 0, -1}, { -1, -1, 16, 9, 10},
|
|
{ -1, -1, 16, 10, 10}, { -1, -1, 10, 1, 11},
|
|
{227, 242, -1, 0, -1}, {228, 235, -1, 0, -1},
|
|
{229, 232, -1, 0, -1}, {230, 231, -1, 0, -1},
|
|
{ -1, -1, 16, 2, 11}, { -1, -1, 16, 3, 11},
|
|
{233, 234, -1, 0, -1}, { -1, -1, 16, 4, 11},
|
|
{ -1, -1, 16, 5, 11}, {236, 239, -1, 0, -1},
|
|
{237, 238, -1, 0, -1}, { -1, -1, 16, 6, 11},
|
|
{ -1, -1, 16, 7, 11}, {240, 241, -1, 0, -1},
|
|
{ -1, -1, 16, 8, 11}, { -1, -1, 16, 9, 11},
|
|
{243, 251, -1, 0, -1}, {244, 248, -1, 0, -1},
|
|
{245, 247, -1, 0, -1}, { -1, -1, 16, 10, 11},
|
|
{ -1, -1, 10, 1, 12}, { -1, -1, 16, 2, 12},
|
|
{249, 250, -1, 0, -1}, { -1, -1, 16, 3, 12},
|
|
{ -1, -1, 16, 4, 12}, {252, 255, -1, 0, -1},
|
|
{253, 254, -1, 0, -1}, { -1, -1, 16, 5, 12},
|
|
{ -1, -1, 16, 6, 12}, {256, 257, -1, 0, -1},
|
|
{ -1, -1, 16, 7, 12}, { -1, -1, 16, 8, 12},
|
|
{259, 292, -1, 0, -1}, {260, 277, -1, 0, -1},
|
|
{261, 270, -1, 0, -1}, {262, 267, -1, 0, -1},
|
|
{263, 264, -1, 0, -1}, { -1, -1, 16, 9, 12},
|
|
{ -1, -1, 16, 10, 12}, {266, 322, -1, 0, -1},
|
|
{ -1, -1, 11, 1, 13}, {268, 269, -1, 0, -1},
|
|
{ -1, -1, 16, 2, 13}, { -1, -1, 16, 3, 13},
|
|
{271, 274, -1, 0, -1}, {272, 273, -1, 0, -1},
|
|
{ -1, -1, 16, 4, 13}, { -1, -1, 16, 5, 13},
|
|
{275, 276, -1, 0, -1}, { -1, -1, 16, 6, 13},
|
|
{ -1, -1, 16, 7, 13}, {278, 285, -1, 0, -1},
|
|
{279, 282, -1, 0, -1}, {280, 281, -1, 0, -1},
|
|
{ -1, -1, 16, 8, 13}, { -1, -1, 16, 9, 13},
|
|
{283, 284, -1, 0, -1}, { -1, -1, 16, 10, 13},
|
|
{ -1, -1, 16, 1, 14}, {286, 289, -1, 0, -1},
|
|
{287, 288, -1, 0, -1}, { -1, -1, 16, 2, 14},
|
|
{ -1, -1, 16, 3, 14}, {290, 291, -1, 0, -1},
|
|
{ -1, -1, 16, 4, 14}, { -1, -1, 16, 5, 14},
|
|
{293, 308, -1, 0, -1}, {294, 301, -1, 0, -1},
|
|
{295, 298, -1, 0, -1}, {296, 297, -1, 0, -1},
|
|
{ -1, -1, 16, 6, 14}, { -1, -1, 16, 7, 14},
|
|
{299, 300, -1, 0, -1}, { -1, -1, 16, 8, 14},
|
|
{ -1, -1, 16, 9, 14}, {302, 305, -1, 0, -1},
|
|
{303, 304, -1, 0, -1}, { -1, -1, 16, 10, 14},
|
|
{ -1, -1, 16, 1, 15}, {306, 307, -1, 0, -1},
|
|
{ -1, -1, 16, 2, 15}, { -1, -1, 16, 3, 15},
|
|
{309, 316, -1, 0, -1}, {310, 313, -1, 0, -1},
|
|
{311, 312, -1, 0, -1}, { -1, -1, 16, 4, 15},
|
|
{ -1, -1, 16, 5, 15}, {314, 315, -1, 0, -1},
|
|
{ -1, -1, 16, 6, 15}, { -1, -1, 16, 7, 15},
|
|
{317, 320, -1, 0, -1}, {318, 319, -1, 0, -1},
|
|
{ -1, -1, 16, 8, 15}, { -1, -1, 16, 9, 15},
|
|
{321, -1, -1, 0, -1}, { -1, -1, 16, 10, 15},
|
|
{ -1, -1, 11, 0, 16}, { -1, -1, 4, 0, -1},
|
|
};
|
|
|
|
static const struct tree_node treeUVAC[] = {
|
|
{ 1, 3, -1, 0, -1}, {323, 2, -1, 0, -1},
|
|
{ -1, -1, 2, 1, 0}, { 4, 8, -1, 0, -1},
|
|
{ 5, 6, -1, 0, -1}, { -1, -1, 3, 2, 0},
|
|
{ 7, 37, -1, 0, -1}, { -1, -1, 4, 3, 0},
|
|
{ 9, 13, -1, 0, -1}, { 10, 60, -1, 0, -1},
|
|
{ 11, 12, -1, 0, -1}, { -1, -1, 5, 4, 0},
|
|
{ -1, -1, 5, 5, 0}, { 14, 17, -1, 0, -1},
|
|
{ 15, 97, -1, 0, -1}, { 16, 38, -1, 0, -1},
|
|
{ -1, -1, 6, 6, 0}, { 18, 21, -1, 0, -1},
|
|
{ 19, 39, -1, 0, -1}, { 20, 135, -1, 0, -1},
|
|
{ -1, -1, 7, 7, 0}, { 22, 26, -1, 0, -1},
|
|
{ 82, 23, -1, 0, -1}, { 24, 99, -1, 0, -1},
|
|
{ 25, 42, -1, 0, -1}, { -1, -1, 9, 8, 0},
|
|
{ 27, 31, -1, 0, -1}, {211, 28, -1, 0, -1},
|
|
{248, 29, -1, 0, -1}, { 30, 63, -1, 0, -1},
|
|
{ -1, -1, 10, 9, 0}, { 43, 32, -1, 0, -1},
|
|
{ 33, 48, -1, 0, -1}, {153, 34, -1, 0, -1},
|
|
{ 35, 64, -1, 0, -1}, { 36, 47, -1, 0, -1},
|
|
{ -1, -1, 12, 10, 0}, { -1, -1, 4, 1, 1},
|
|
{ -1, -1, 6, 2, 1}, {152, 40, -1, 0, -1},
|
|
{ 41, 62, -1, 0, -1}, { -1, -1, 8, 3, 1},
|
|
{ -1, -1, 9, 4, 1}, { 84, 44, -1, 0, -1},
|
|
{322, 45, -1, 0, -1}, { 46, 136, -1, 0, -1},
|
|
{ -1, -1, 11, 5, 1}, { -1, -1, 12, 6, 1},
|
|
{ 49, 189, -1, 0, -1}, { 50, 119, -1, 0, -1},
|
|
{ 51, 76, -1, 0, -1}, { 66, 52, -1, 0, -1},
|
|
{ 53, 69, -1, 0, -1}, { 54, 57, -1, 0, -1},
|
|
{ 55, 56, -1, 0, -1}, { -1, -1, 16, 7, 1},
|
|
{ -1, -1, 16, 8, 1}, { 58, 59, -1, 0, -1},
|
|
{ -1, -1, 16, 9, 1}, { -1, -1, 16, 10, 1},
|
|
{ 61, 81, -1, 0, -1}, { -1, -1, 5, 1, 2},
|
|
{ -1, -1, 8, 2, 2}, { -1, -1, 10, 3, 2},
|
|
{ 65, 86, -1, 0, -1}, { -1, -1, 12, 4, 2},
|
|
{286, 67, -1, 0, -1}, { 68, 304, -1, 0, -1},
|
|
{ -1, -1, 15, 5, 2}, { 70, 73, -1, 0, -1},
|
|
{ 71, 72, -1, 0, -1}, { -1, -1, 16, 6, 2},
|
|
{ -1, -1, 16, 7, 2}, { 74, 75, -1, 0, -1},
|
|
{ -1, -1, 16, 8, 2}, { -1, -1, 16, 9, 2},
|
|
{ 77, 102, -1, 0, -1}, { 78, 91, -1, 0, -1},
|
|
{ 79, 88, -1, 0, -1}, { 80, 87, -1, 0, -1},
|
|
{ -1, -1, 16, 10, 2}, { -1, -1, 5, 1, 3},
|
|
{ 83, 171, -1, 0, -1}, { -1, -1, 8, 2, 3},
|
|
{ 85, 117, -1, 0, -1}, { -1, -1, 10, 3, 3},
|
|
{ -1, -1, 12, 4, 3}, { -1, -1, 16, 5, 3},
|
|
{ 89, 90, -1, 0, -1}, { -1, -1, 16, 6, 3},
|
|
{ -1, -1, 16, 7, 3}, { 92, 95, -1, 0, -1},
|
|
{ 93, 94, -1, 0, -1}, { -1, -1, 16, 8, 3},
|
|
{ -1, -1, 16, 9, 3}, { 96, 101, -1, 0, -1},
|
|
{ -1, -1, 16, 10, 3}, { 98, 116, -1, 0, -1},
|
|
{ -1, -1, 6, 1, 4}, {100, 188, -1, 0, -1},
|
|
{ -1, -1, 9, 2, 4}, { -1, -1, 16, 3, 4},
|
|
{103, 110, -1, 0, -1}, {104, 107, -1, 0, -1},
|
|
{105, 106, -1, 0, -1}, { -1, -1, 16, 4, 4},
|
|
{ -1, -1, 16, 5, 4}, {108, 109, -1, 0, -1},
|
|
{ -1, -1, 16, 6, 4}, { -1, -1, 16, 7, 4},
|
|
{111, 114, -1, 0, -1}, {112, 113, -1, 0, -1},
|
|
{ -1, -1, 16, 8, 4}, { -1, -1, 16, 9, 4},
|
|
{115, 118, -1, 0, -1}, { -1, -1, 16, 10, 4},
|
|
{ -1, -1, 6, 1, 5}, { -1, -1, 10, 2, 5},
|
|
{ -1, -1, 16, 3, 5}, {120, 156, -1, 0, -1},
|
|
{121, 138, -1, 0, -1}, {122, 129, -1, 0, -1},
|
|
{123, 126, -1, 0, -1}, {124, 125, -1, 0, -1},
|
|
{ -1, -1, 16, 4, 5}, { -1, -1, 16, 5, 5},
|
|
{127, 128, -1, 0, -1}, { -1, -1, 16, 6, 5},
|
|
{ -1, -1, 16, 7, 5}, {130, 133, -1, 0, -1},
|
|
{131, 132, -1, 0, -1}, { -1, -1, 16, 8, 5},
|
|
{ -1, -1, 16, 9, 5}, {134, 137, -1, 0, -1},
|
|
{ -1, -1, 16, 10, 5}, { -1, -1, 7, 1, 6},
|
|
{ -1, -1, 11, 2, 6}, { -1, -1, 16, 3, 6},
|
|
{139, 146, -1, 0, -1}, {140, 143, -1, 0, -1},
|
|
{141, 142, -1, 0, -1}, { -1, -1, 16, 4, 6},
|
|
{ -1, -1, 16, 5, 6}, {144, 145, -1, 0, -1},
|
|
{ -1, -1, 16, 6, 6}, { -1, -1, 16, 7, 6},
|
|
{147, 150, -1, 0, -1}, {148, 149, -1, 0, -1},
|
|
{ -1, -1, 16, 8, 6}, { -1, -1, 16, 9, 6},
|
|
{151, 155, -1, 0, -1}, { -1, -1, 16, 10, 6},
|
|
{ -1, -1, 7, 1, 7}, {154, 267, -1, 0, -1},
|
|
{ -1, -1, 11, 2, 7}, { -1, -1, 16, 3, 7},
|
|
{157, 173, -1, 0, -1}, {158, 165, -1, 0, -1},
|
|
{159, 162, -1, 0, -1}, {160, 161, -1, 0, -1},
|
|
{ -1, -1, 16, 4, 7}, { -1, -1, 16, 5, 7},
|
|
{163, 164, -1, 0, -1}, { -1, -1, 16, 6, 7},
|
|
{ -1, -1, 16, 7, 7}, {166, 169, -1, 0, -1},
|
|
{167, 168, -1, 0, -1}, { -1, -1, 16, 8, 7},
|
|
{ -1, -1, 16, 9, 7}, {170, 172, -1, 0, -1},
|
|
{ -1, -1, 16, 10, 7}, { -1, -1, 8, 1, 8},
|
|
{ -1, -1, 16, 2, 8}, {174, 181, -1, 0, -1},
|
|
{175, 178, -1, 0, -1}, {176, 177, -1, 0, -1},
|
|
{ -1, -1, 16, 3, 8}, { -1, -1, 16, 4, 8},
|
|
{179, 180, -1, 0, -1}, { -1, -1, 16, 5, 8},
|
|
{ -1, -1, 16, 6, 8}, {182, 185, -1, 0, -1},
|
|
{183, 184, -1, 0, -1}, { -1, -1, 16, 7, 8},
|
|
{ -1, -1, 16, 8, 8}, {186, 187, -1, 0, -1},
|
|
{ -1, -1, 16, 9, 8}, { -1, -1, 16, 10, 8},
|
|
{ -1, -1, 9, 1, 9}, {190, 257, -1, 0, -1},
|
|
{191, 224, -1, 0, -1}, {192, 207, -1, 0, -1},
|
|
{193, 200, -1, 0, -1}, {194, 197, -1, 0, -1},
|
|
{195, 196, -1, 0, -1}, { -1, -1, 16, 2, 9},
|
|
{ -1, -1, 16, 3, 9}, {198, 199, -1, 0, -1},
|
|
{ -1, -1, 16, 4, 9}, { -1, -1, 16, 5, 9},
|
|
{201, 204, -1, 0, -1}, {202, 203, -1, 0, -1},
|
|
{ -1, -1, 16, 6, 9}, { -1, -1, 16, 7, 9},
|
|
{205, 206, -1, 0, -1}, { -1, -1, 16, 8, 9},
|
|
{ -1, -1, 16, 9, 9}, {208, 217, -1, 0, -1},
|
|
{209, 214, -1, 0, -1}, {210, 213, -1, 0, -1},
|
|
{ -1, -1, 16, 10, 9}, {212, 230, -1, 0, -1},
|
|
{ -1, -1, 9, 1, 10}, { -1, -1, 16, 2, 10},
|
|
{215, 216, -1, 0, -1}, { -1, -1, 16, 3, 10},
|
|
{ -1, -1, 16, 4, 10}, {218, 221, -1, 0, -1},
|
|
{219, 220, -1, 0, -1}, { -1, -1, 16, 5, 10},
|
|
{ -1, -1, 16, 6, 10}, {222, 223, -1, 0, -1},
|
|
{ -1, -1, 16, 7, 10}, { -1, -1, 16, 8, 10},
|
|
{225, 241, -1, 0, -1}, {226, 234, -1, 0, -1},
|
|
{227, 231, -1, 0, -1}, {228, 229, -1, 0, -1},
|
|
{ -1, -1, 16, 9, 10}, { -1, -1, 16, 10, 10},
|
|
{ -1, -1, 9, 1, 11}, {232, 233, -1, 0, -1},
|
|
{ -1, -1, 16, 2, 11}, { -1, -1, 16, 3, 11},
|
|
{235, 238, -1, 0, -1}, {236, 237, -1, 0, -1},
|
|
{ -1, -1, 16, 4, 11}, { -1, -1, 16, 5, 11},
|
|
{239, 240, -1, 0, -1}, { -1, -1, 16, 6, 11},
|
|
{ -1, -1, 16, 7, 11}, {242, 250, -1, 0, -1},
|
|
{243, 246, -1, 0, -1}, {244, 245, -1, 0, -1},
|
|
{ -1, -1, 16, 8, 11}, { -1, -1, 16, 9, 11},
|
|
{247, 249, -1, 0, -1}, { -1, -1, 16, 10, 11},
|
|
{ -1, -1, 9, 1, 12}, { -1, -1, 16, 2, 12},
|
|
{251, 254, -1, 0, -1}, {252, 253, -1, 0, -1},
|
|
{ -1, -1, 16, 3, 12}, { -1, -1, 16, 4, 12},
|
|
{255, 256, -1, 0, -1}, { -1, -1, 16, 5, 12},
|
|
{ -1, -1, 16, 6, 12}, {258, 291, -1, 0, -1},
|
|
{259, 275, -1, 0, -1}, {260, 268, -1, 0, -1},
|
|
{261, 264, -1, 0, -1}, {262, 263, -1, 0, -1},
|
|
{ -1, -1, 16, 7, 12}, { -1, -1, 16, 8, 12},
|
|
{265, 266, -1, 0, -1}, { -1, -1, 16, 9, 12},
|
|
{ -1, -1, 16, 10, 12}, { -1, -1, 11, 1, 13},
|
|
{269, 272, -1, 0, -1}, {270, 271, -1, 0, -1},
|
|
{ -1, -1, 16, 2, 13}, { -1, -1, 16, 3, 13},
|
|
{273, 274, -1, 0, -1}, { -1, -1, 16, 4, 13},
|
|
{ -1, -1, 16, 5, 13}, {276, 283, -1, 0, -1},
|
|
{277, 280, -1, 0, -1}, {278, 279, -1, 0, -1},
|
|
{ -1, -1, 16, 6, 13}, { -1, -1, 16, 7, 13},
|
|
{281, 282, -1, 0, -1}, { -1, -1, 16, 8, 13},
|
|
{ -1, -1, 16, 9, 13}, {284, 288, -1, 0, -1},
|
|
{285, 287, -1, 0, -1}, { -1, -1, 16, 10, 13},
|
|
{ -1, -1, 14, 1, 14}, { -1, -1, 16, 2, 14},
|
|
{289, 290, -1, 0, -1}, { -1, -1, 16, 3, 14},
|
|
{ -1, -1, 16, 4, 14}, {292, 308, -1, 0, -1},
|
|
{293, 300, -1, 0, -1}, {294, 297, -1, 0, -1},
|
|
{295, 296, -1, 0, -1}, { -1, -1, 16, 5, 14},
|
|
{ -1, -1, 16, 6, 14}, {298, 299, -1, 0, -1},
|
|
{ -1, -1, 16, 7, 14}, { -1, -1, 16, 8, 14},
|
|
{301, 305, -1, 0, -1}, {302, 303, -1, 0, -1},
|
|
{ -1, -1, 16, 9, 14}, { -1, -1, 16, 10, 14},
|
|
{ -1, -1, 15, 1, 15}, {306, 307, -1, 0, -1},
|
|
{ -1, -1, 16, 2, 15}, { -1, -1, 16, 3, 15},
|
|
{309, 316, -1, 0, -1}, {310, 313, -1, 0, -1},
|
|
{311, 312, -1, 0, -1}, { -1, -1, 16, 4, 15},
|
|
{ -1, -1, 16, 5, 15}, {314, 315, -1, 0, -1},
|
|
{ -1, -1, 16, 6, 15}, { -1, -1, 16, 7, 15},
|
|
{317, 320, -1, 0, -1}, {318, 319, -1, 0, -1},
|
|
{ -1, -1, 16, 8, 15}, { -1, -1, 16, 9, 15},
|
|
{321, -1, -1, 0, -1}, { -1, -1, 16, 10, 15},
|
|
{ -1, -1, 10, 0, 16}, { -1, -1, 2, 0, -1},
|
|
};
|
|
|
|
static const struct tree_node treeYDC[] = {
|
|
{ 1, 6, -1, 0}, { 2, 3, -1, 0},
|
|
{ -1, -1, 2, 0}, { 4, 5, -1, 0},
|
|
{ -1, -1, 3, 1}, { -1, -1, 3, 2},
|
|
{ 7, 10, -1, 0}, { 8, 9, -1, 0},
|
|
{ -1, -1, 3, 3}, { -1, -1, 3, 4},
|
|
{ 11, 12, -1, 0}, { -1, -1, 3, 5},
|
|
{ 13, 14, -1, 0}, { -1, -1, 4, 6},
|
|
{ 15, 16, -1, 0}, { -1, -1, 5, 7},
|
|
{ 17, 18, -1, 0}, { -1, -1, 6, 8},
|
|
{ 19, 20, -1, 0}, { -1, -1, 7, 9},
|
|
{ 21, 22, -1, 0}, { -1, -1, 8, 10},
|
|
{ 23, -1, -1, 0}, { -1, -1, 9, 11},
|
|
};
|
|
|
|
static const struct tree_node treeUVDC[] = {
|
|
{ 1, 4, -1, 0}, { 2, 3, -1, 0},
|
|
{ -1, -1, 2, 0}, { -1, -1, 2, 1},
|
|
{ 5, 6, -1, 0}, { -1, -1, 2, 2},
|
|
{ 7, 8, -1, 0}, { -1, -1, 3, 3},
|
|
{ 9, 10, -1, 0}, { -1, -1, 4, 4},
|
|
{ 11, 12, -1, 0}, { -1, -1, 5, 5},
|
|
{ 13, 14, -1, 0}, { -1, -1, 6, 6},
|
|
{ 15, 16, -1, 0}, { -1, -1, 7, 7},
|
|
{ 17, 18, -1, 0}, { -1, -1, 8, 8},
|
|
{ 19, 20, -1, 0}, { -1, -1, 9, 9},
|
|
{ 21, 22, -1, 0}, { -1, -1, 10, 10},
|
|
{ 23, -1, -1, 0}, { -1, -1, 11, 11},
|
|
};
|
|
|
|
/******************************************************************************
|
|
* Huffman Decoder
|
|
******************************************************************************/
|
|
|
|
/* Note: There is no penalty for passing the tree as an argument, since dummy
|
|
* args are passed anyway (to maintain 16-byte stack alignment), and since the
|
|
* address is loaded into a register either way. */
|
|
|
|
/* If no node is found, coeffbits and skip will not be modified */
|
|
/* Return: Depth of node found, or -1 if invalid input code */
|
|
static int
|
|
getNodeAC(unsigned int in, signed char *coeffbits, signed char *skip,
|
|
const struct tree_node *tree)
|
|
{
|
|
int node = 0;
|
|
int i = 0;
|
|
int depth;
|
|
|
|
do {
|
|
if ((in & 0x80000000) == 0)
|
|
node = tree[node].left;
|
|
else
|
|
node = tree[node].right;
|
|
|
|
if (node == -1)
|
|
break;
|
|
|
|
depth = tree[node].depth;
|
|
|
|
/* Is it a leaf? If not, branch downward */
|
|
if (depth != -1) {
|
|
*coeffbits = tree[node].coeffbits;
|
|
*skip = tree[node].skip;
|
|
return depth;
|
|
}
|
|
|
|
in <<= 1;
|
|
++i;
|
|
} while (i <= 15);
|
|
|
|
return -1;
|
|
}
|
|
|
|
/* If no node is found, coeffbits will not be modified */
|
|
/* Return: Depth of node found, or -1 if invalid input code */
|
|
static int
|
|
getNodeDC(unsigned int in, signed char *coeffbits, const struct tree_node *tree)
|
|
{
|
|
int node = 0;
|
|
int i = 0;
|
|
int depth;
|
|
|
|
do {
|
|
if ((in & 0x80000000) == 0)
|
|
node = tree[node].left;
|
|
else
|
|
node = tree[node].right;
|
|
|
|
if (node == -1)
|
|
break;
|
|
|
|
depth = tree[node].depth;
|
|
|
|
/* Is it a leaf? If not, branch downward */
|
|
if (depth != -1) {
|
|
*coeffbits = tree[node].coeffbits;
|
|
return depth;
|
|
}
|
|
|
|
in <<= 1;
|
|
++i;
|
|
} while (i <= 15);
|
|
|
|
return -1;
|
|
}
|
|
|
|
static inline unsigned int
|
|
getBytes(int *rawData, struct comp_info *cinfo)
|
|
{
|
|
int bufLen = cinfo->rawLen;
|
|
int bits = cinfo->bits;
|
|
int bytes = cinfo->bytes;
|
|
unsigned char *in = bytes + (unsigned char *) rawData;
|
|
unsigned char b1, b2, b3, b4, b5;
|
|
unsigned int packedIn;
|
|
|
|
/* Pull 5 bytes out of raw data */
|
|
if (bytes < bufLen - 4) {
|
|
b1 = in[0];
|
|
b2 = in[1];
|
|
b3 = in[2];
|
|
b4 = in[3];
|
|
b5 = in[4];
|
|
} else {
|
|
if (bytes < bufLen - 3) {
|
|
b1 = in[0];
|
|
b2 = in[1];
|
|
b3 = in[2];
|
|
b4 = in[3];
|
|
} else {
|
|
if (bytes < bufLen - 2) {
|
|
b1 = in[0];
|
|
b2 = in[1];
|
|
b3 = in[2];
|
|
} else {
|
|
if (bytes < bufLen - 1) {
|
|
b1 = in[0];
|
|
b2 = in[1];
|
|
} else {
|
|
if (bytes <= bufLen)
|
|
b1 = in[0];
|
|
else
|
|
b1 = 0;
|
|
b2 = 0;
|
|
}
|
|
b3 = 0;
|
|
}
|
|
b4 = 0;
|
|
}
|
|
b5 = 0;
|
|
}
|
|
|
|
/* Pack the bytes */
|
|
packedIn = b1 << 24;
|
|
packedIn += b2 << 16;
|
|
packedIn += b3 << 8;
|
|
packedIn += b4;
|
|
|
|
if (bits != 0) {
|
|
packedIn = packedIn << bits;
|
|
packedIn += b5 >> (8 - bits);
|
|
}
|
|
|
|
return packedIn;
|
|
}
|
|
|
|
static int
|
|
getACCoefficient(int *rawData, int *coeff, struct comp_info *cinfo,
|
|
const struct tree_node *tree)
|
|
{
|
|
int input, bits, bytes, tmp_c;
|
|
signed char coeffbits = 0;
|
|
signed char skip = 0;
|
|
|
|
input = getBytes(rawData, cinfo);
|
|
bits = getNodeAC(input, &coeffbits, &skip, tree);
|
|
|
|
if (coeffbits) {
|
|
input = input << (bits - 1);
|
|
input &= 0x7fffffff;
|
|
if (!(input & 0x40000000))
|
|
input |= 0x80000000;
|
|
|
|
tmp_c = input >> (31 - coeffbits);
|
|
if (tmp_c < 0)
|
|
tmp_c++;
|
|
*coeff = tmp_c;
|
|
|
|
bits += coeffbits;
|
|
}
|
|
|
|
bytes = (bits + cinfo->bits) >> 3;
|
|
cinfo->bytes += bytes;
|
|
cinfo->bits += bits - (bytes << 3);
|
|
|
|
return skip;
|
|
}
|
|
|
|
static void
|
|
getDCCoefficient(int *rawData, int *coeff, struct comp_info *cinfo,
|
|
const struct tree_node *tree)
|
|
{
|
|
int input, bits, bytes, tmp_c;
|
|
signed char coeffbits = 0;
|
|
|
|
input = getBytes(rawData, cinfo);
|
|
bits = getNodeDC(input, &coeffbits, tree);
|
|
|
|
if (bits == -1) {
|
|
bits = 1; /* Try to re-sync at the next bit */
|
|
*coeff = 0; /* Indicates no change from last DC */
|
|
} else {
|
|
|
|
input = input << (bits - 1);
|
|
input &= 0x7fffffff;
|
|
if (!(input & 0x40000000))
|
|
input |= 0x80000000;
|
|
|
|
tmp_c = input >> (31 - coeffbits);
|
|
if (tmp_c < 0)
|
|
tmp_c++;
|
|
*coeff = tmp_c;
|
|
|
|
bits += coeffbits;
|
|
}
|
|
|
|
bytes = (bits + cinfo->bits) >> 3;
|
|
cinfo->bytes += bytes;
|
|
cinfo->bits += bits - (bytes << 3);
|
|
}
|
|
|
|
/* For AC coefficients, here is what the "skip" value means:
|
|
* -1: Either the 8x4 block has ended, or the decoding failed.
|
|
* 0: Use the returned coeff. Don't skip anything.
|
|
* 1-15: The next <skip> coeffs are zero. The returned coeff is used.
|
|
* 16: The next 16 coeffs are zero. The returned coeff is ignored.
|
|
*
|
|
* You must ensure that the C[] array not be overrun, or stack corruption will
|
|
* result.
|
|
*/
|
|
static void
|
|
huffmanDecoderY(int *C, int *pIn, struct comp_info *cinfo)
|
|
{
|
|
int coeff = 0;
|
|
int i = 1;
|
|
int k, skip;
|
|
|
|
getDCCoefficient(pIn, C, cinfo, treeYDC);
|
|
|
|
i = 1;
|
|
do {
|
|
skip = getACCoefficient(pIn, &coeff, cinfo, treeYAC);
|
|
|
|
if (skip == -1) {
|
|
break;
|
|
}
|
|
if (skip == 0) {
|
|
C[i++] = coeff;
|
|
} else if (skip == 16) {
|
|
k = 16;
|
|
if (i > 16)
|
|
k = 32 - i;
|
|
|
|
while (k--)
|
|
C[i++] = 0;
|
|
} else {
|
|
k = skip;
|
|
if (skip > 31 - i)
|
|
k = 31 - i;
|
|
|
|
while (k--)
|
|
C[i++] = 0;
|
|
|
|
C[i++] = coeff;
|
|
}
|
|
} while (i <= 31);
|
|
|
|
if (skip == -1)
|
|
while (i <= 31)
|
|
C[i++] = 0;
|
|
else
|
|
getACCoefficient(pIn, &coeff, cinfo, treeYAC);
|
|
}
|
|
|
|
/* Same as huffmanDecoderY, except for the tables used */
|
|
static void
|
|
huffmanDecoderUV(int *C, int *pIn, struct comp_info *cinfo)
|
|
{
|
|
int coeff = 0;
|
|
int i = 1;
|
|
int k, skip;
|
|
|
|
getDCCoefficient(pIn, C, cinfo, treeUVDC);
|
|
|
|
i = 1;
|
|
do {
|
|
skip = getACCoefficient(pIn, &coeff, cinfo, treeUVAC);
|
|
|
|
if (skip == -1) {
|
|
break;
|
|
}
|
|
if (skip == 0) {
|
|
C[i++] = coeff;
|
|
} else if (skip == 16) {
|
|
k = 16;
|
|
if (i > 16)
|
|
k = 32 - i;
|
|
|
|
while (k--)
|
|
C[i++] = 0;
|
|
} else {
|
|
k = skip;
|
|
if (skip > 31 - i)
|
|
k = 31 - i;
|
|
|
|
while (k--)
|
|
C[i++] = 0;
|
|
|
|
C[i++] = coeff;
|
|
}
|
|
} while (i <= 31);
|
|
|
|
if (skip == -1)
|
|
while (i <= 31)
|
|
C[i++] = 0;
|
|
else
|
|
getACCoefficient(pIn, &coeff, cinfo, treeUVAC);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* iDCT Functions
|
|
******************************************************************************/
|
|
|
|
#ifndef APPROXIMATE_MUL_BY_SHIFT
|
|
|
|
#define IDCT_MESSAGE "iDCT with multiply"
|
|
|
|
#define TIMES_16382(u) ((u) ? 16382 * (u) : 0)
|
|
#define TIMES_23168(u) ((u) ? 23168 * (u) : 0)
|
|
#define TIMES_30270(u) ((u) ? 30270 * (u) : 0)
|
|
#define TIMES_41986(u) ((u) ? 41986 * (u) : 0)
|
|
#define TIMES_35594(u) ((u) ? 35594 * (u) : 0)
|
|
#define TIMES_23783(u) ((u) ? 23783 * (u) : 0)
|
|
#define TIMES_8351(u) ((u) ? 8351 * (u) : 0)
|
|
#define TIMES_17391(u) ((u) ? 17391 * (u) : 0)
|
|
#define TIMES_14743(u) ((u) ? 14743 * (u) : 0)
|
|
#define TIMES_9851(u) ((u) ? 9851 * (u) : 0)
|
|
#define TIMES_3459(u) ((u) ? 3459 * (u) : 0)
|
|
#define TIMES_32134(u) ((u) ? 32134 * (u) : 0)
|
|
#define TIMES_27242(u) ((u) ? 27242 * (u) : 0)
|
|
#define TIMES_18202(u) ((u) ? 18202 * (u) : 0)
|
|
#define TIMES_6392(u) ((u) ? 6392 * (u) : 0)
|
|
#define TIMES_39550(u) ((u) ? 39550 * (u) : 0)
|
|
#define TIMES_6785(u) ((u) ? 6785 * (u) : 0)
|
|
#define TIMES_12538(u) ((u) ? 12538 * (u) : 0)
|
|
|
|
#else
|
|
|
|
#define IDCT_MESSAGE "iDCT with shift"
|
|
|
|
#define TIMES_16382(u) ((u) ? x = (u), (x << 14) - (x << 1) : 0)
|
|
#define TIMES_23168(u) ((u) ? x = (u), (x << 14) + (x << 12) + (x << 11) + (x << 9) : 0)
|
|
#define TIMES_30270(u) ((u) ? x = (u), (x << 15) - (x << 11) : 0)
|
|
#define TIMES_41986(u) ((u) ? x = (u), (x << 15) + (x << 13) + (x << 10) : 0)
|
|
#define TIMES_35594(u) ((u) ? x = (u), (x << 15) + (x << 11) + (x << 9) + (x << 8) : 0)
|
|
#define TIMES_23783(u) ((u) ? x = (u), (x << 14) + (x << 13) - (x << 9) - (x << 8) : 0)
|
|
#define TIMES_8351(u) ((u) ? x = (u), (x << 13) : 0)
|
|
#define TIMES_17391(u) ((u) ? x = (u), (x << 14) + (x << 10) : 0)
|
|
#define TIMES_14743(u) ((u) ? x = (u), (x << 14) - (x << 10) - (x << 9) : 0)
|
|
#define TIMES_9851(u) ((u) ? x = (u), (x << 13) + (x << 10) + (x << 9) : 0)
|
|
#define TIMES_3459(u) ((u) ? x = (u), (x << 12) - (x << 9) : 0)
|
|
#define TIMES_32134(u) ((u) ? x = (u), (x << 15) - (x << 9) : 0)
|
|
#define TIMES_27242(u) ((u) ? x = (u), (x << 14) + (x << 13) + (x << 11) + (x << 9) : 0)
|
|
#define TIMES_18202(u) ((u) ? x = (u), (x << 14) + (x << 11) - (x << 8) : 0)
|
|
#define TIMES_6392(u) ((u) ? x = (u), (x << 13) - (x << 11) + (x << 8) : 0)
|
|
#define TIMES_39550(u) ((u) ? x = (u), (x << 15) + (x << 12) + (x << 11) + (x << 9) : 0)
|
|
#define TIMES_6785(u) ((u) ? x = (u), (x << 12) + (x << 11) + (x << 9) : 0)
|
|
#define TIMES_12538(u) ((u) ? x = (u), (x << 13) + (x << 12) + (x << 8) : 0)
|
|
|
|
/*
|
|
* The variables C0, C4, C16 and C20 can also be removed from the algorithm
|
|
* if APPROXIMATE_MUL_BY_SHIFTS is defined. They store correction values
|
|
* and can be considered insignificant.
|
|
*/
|
|
|
|
#endif
|
|
|
|
static void
|
|
DCT_8x4(int *coeff, unsigned char *out)
|
|
/* pre: coeff == coefficients
|
|
post: coeff != coefficients
|
|
** DO NOT ASSUME coeff TO BE THE SAME BEFORE AND AFTER CALLING THIS FUNCTION!
|
|
*/
|
|
{
|
|
register int base, val1, val2, val3;
|
|
int tmp1, tmp2;
|
|
int C4, C16, C20;
|
|
int C2_18, C6_22, C1_17, C3_19, C5_21, C7_23;
|
|
register int t;
|
|
#ifdef APPROXIMATE_MUL_BY_SHIFT
|
|
register int x;
|
|
#endif
|
|
|
|
C4 = coeff[4];
|
|
C16 = coeff[16];
|
|
C20 = coeff[20];
|
|
|
|
coeff[0] = TIMES_23168(coeff[0]);
|
|
coeff[4] = TIMES_23168(coeff[4]);
|
|
coeff[16] = TIMES_23168(coeff[16]);
|
|
coeff[20] = TIMES_23168(coeff[20]);
|
|
|
|
C2_18 = coeff[2] + coeff[18];
|
|
C6_22 = coeff[6] + coeff[22];
|
|
C1_17 = coeff[1] + coeff[17];
|
|
C3_19 = coeff[3] + coeff[19];
|
|
C5_21 = coeff[5] + coeff[21];
|
|
C7_23 = coeff[7] + coeff[23];
|
|
|
|
// 0,7,25,32
|
|
|
|
base = 0x1000000;
|
|
base += coeff[0] + coeff[4] + coeff[16] + coeff[20];
|
|
base += TIMES_30270(C2_18);
|
|
base += TIMES_12538(C6_22);
|
|
|
|
val1 = TIMES_41986(coeff[9]);
|
|
val1 += TIMES_35594(coeff[11]);
|
|
val1 += TIMES_23783(coeff[13]);
|
|
val1 += TIMES_8351(coeff[15]);
|
|
val1 += TIMES_17391(coeff[25]);
|
|
val1 += TIMES_14743(coeff[27]);
|
|
val1 += TIMES_9851(coeff[29]);
|
|
val1 += TIMES_3459(coeff[31]);
|
|
|
|
val2 = TIMES_32134(C1_17);
|
|
val2 += TIMES_27242(C3_19);
|
|
val2 += TIMES_18202(C5_21);
|
|
val2 += TIMES_6392(C7_23);
|
|
|
|
val3 = TIMES_39550(coeff[10]);
|
|
val3 += TIMES_16382(coeff[14] + coeff[26]);
|
|
val3 += TIMES_6785(coeff[30]);
|
|
val3 += TIMES_30270(coeff[8] + coeff[12]);
|
|
val3 += TIMES_12538(coeff[24] + coeff[28]);
|
|
|
|
t = (base + val1 + val2 + val3) >> 17;
|
|
out[0] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 - val2 + val3 - C4 - C20) >> 17;
|
|
out[7] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 + val2 - val3 - C16 - C20) >> 17;
|
|
out[24] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base + val1 - val2 - val3 - C4 - C16 - C20) >> 17;
|
|
out[31] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
|
|
//1,6,25,30
|
|
|
|
base = 0x1000000;
|
|
base += coeff[0] - coeff[4] + coeff[16] - coeff[20];
|
|
base += TIMES_12538(C2_18);
|
|
base -= TIMES_30270(C6_22);
|
|
|
|
val1 = TIMES_35594(coeff[9]);
|
|
val1 -= TIMES_8351(coeff[11]);
|
|
val1 -= TIMES_41986(coeff[13]);
|
|
val1 -= TIMES_23783(coeff[15]);
|
|
val1 -= TIMES_14743(coeff[25]);
|
|
val1 -= TIMES_3459(coeff[27]);
|
|
val1 -= TIMES_17391(coeff[29]);
|
|
val1 -= TIMES_9851(coeff[31]);
|
|
|
|
val2 = TIMES_27242(C1_17);
|
|
val2 -= TIMES_6392(C3_19);
|
|
val2 -= TIMES_32134(C5_21);
|
|
val2 -= TIMES_18202(C7_23);
|
|
|
|
val3 = TIMES_16382(coeff[10] - coeff[30]);
|
|
val3 -= TIMES_39550(coeff[14]);
|
|
val3 += TIMES_6785(coeff[26]);
|
|
val3 += TIMES_12538(coeff[24] - coeff[28]);
|
|
val3 += TIMES_30270(coeff[8] - coeff[12]);
|
|
|
|
t = (base + val1 + val2 + val3 + C4 + C20) >> 17;
|
|
out[1] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 - val2 + val3) >> 17;
|
|
out[6] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 + val2 - val3 + C4 - C16 + C20) >> 17;
|
|
out[25] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base + val1 - val2 - val3 + C20) >> 17;
|
|
out[30] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
|
|
//2,5,26,29
|
|
|
|
base = 0x1000000;
|
|
base += coeff[0] - coeff[4] + coeff[16] - coeff[20];
|
|
base -= TIMES_12538(C2_18);
|
|
base += TIMES_30270(C6_22);
|
|
|
|
val1 = TIMES_23783(coeff[9]);
|
|
val1 -= TIMES_41986(coeff[11]);
|
|
val1 += TIMES_8351(coeff[13]);
|
|
val1 += TIMES_35594(coeff[15]);
|
|
val1 += TIMES_9851(coeff[25]);
|
|
val1 -= TIMES_17391(coeff[27]);
|
|
val1 += TIMES_3459(coeff[29]);
|
|
val1 += TIMES_14743(coeff[31]);
|
|
|
|
val2 = TIMES_18202(C1_17);
|
|
val2 -= TIMES_32134(C3_19);
|
|
val2 += TIMES_6392(C5_21);
|
|
val2 += TIMES_27242(C7_23);
|
|
|
|
val3 = -TIMES_16382(coeff[10] - coeff[30]);
|
|
val3 += TIMES_39550(coeff[14]);
|
|
val3 -= TIMES_6785(coeff[26]);
|
|
val3 += TIMES_12538(coeff[24] - coeff[28]);
|
|
val3 += TIMES_30270(coeff[8] - coeff[12]);
|
|
|
|
t = (base + val1 + val2 + val3) >> 17;
|
|
out[2] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 - val2 + val3) >> 17;
|
|
out[5] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 + val2 - val3 - C16) >> 17;
|
|
out[26] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base + val1 - val2 - val3 + C4 - C16 + C20) >> 17;
|
|
out[29] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
|
|
//3,4,27,28
|
|
|
|
base = 0x1000000;
|
|
base += coeff[0] + coeff[4] + coeff[16] + coeff[20];
|
|
base -= TIMES_30270(C2_18);
|
|
base -= TIMES_12538(C6_22);
|
|
|
|
val1 = TIMES_8351(coeff[9]);
|
|
val1 -= TIMES_23783(coeff[11]);
|
|
val1 += TIMES_35594(coeff[13]);
|
|
val1 += TIMES_3459(coeff[25]);
|
|
val1 -= TIMES_9851(coeff[27]);
|
|
val1 += TIMES_14743(coeff[29]);
|
|
|
|
val2 = TIMES_6392(C1_17);
|
|
val2 -= TIMES_18202(C3_19);
|
|
val2 += TIMES_27242(C5_21);
|
|
|
|
val3 = -TIMES_39550(coeff[10]);
|
|
val3 += TIMES_16382(coeff[14] + coeff[26]);
|
|
val3 -= TIMES_6785(coeff[30]);
|
|
val3 += TIMES_30270(coeff[8] + coeff[12]);
|
|
val3 += TIMES_12538(coeff[24] + coeff[28]);
|
|
|
|
tmp1 = TIMES_32134(C7_23);
|
|
tmp2 = TIMES_41986(coeff[15]) + TIMES_17391(coeff[31]);
|
|
|
|
t = (base + val1 + val2 + val3 - tmp1 - tmp2 - C4 - C20) >> 17;
|
|
out[3] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 - val2 + val3) >> 17;
|
|
out[4] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 + val2 - val3 - tmp1 + tmp2) >> 17;
|
|
out[27] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base + val1 - val2 - val3 - C16 - C20) >> 17;
|
|
out[28] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
|
|
// Second half
|
|
C2_18 = coeff[2] - coeff[18];
|
|
C6_22 = coeff[6] - coeff[22];
|
|
C1_17 = coeff[1] - coeff[17];
|
|
C3_19 = coeff[3] - coeff[19];
|
|
C5_21 = coeff[5] - coeff[21];
|
|
C7_23 = coeff[7] - coeff[23];
|
|
|
|
// 8,15,16,23
|
|
|
|
base = 0x1000000;
|
|
base += coeff[0] + coeff[4] - coeff[16] - coeff[20];
|
|
base += TIMES_30270(C2_18);
|
|
base += TIMES_12538(C6_22);
|
|
|
|
val1 = TIMES_17391(coeff[9]);
|
|
val1 += TIMES_14743(coeff[11]);
|
|
val1 += TIMES_9851(coeff[13]);
|
|
val1 += TIMES_3459(coeff[15]);
|
|
val1 -= TIMES_41986(coeff[25]);
|
|
val1 -= TIMES_35594(coeff[27]);
|
|
val1 -= TIMES_23783(coeff[29]);
|
|
val1 -= TIMES_8351(coeff[31]);
|
|
|
|
val2 = TIMES_32134(C1_17);
|
|
val2 += TIMES_27242(C3_19);
|
|
val2 += TIMES_18202(C5_21);
|
|
val2 += TIMES_6392(C7_23);
|
|
|
|
val3 = TIMES_16382(coeff[10] - coeff[30]);
|
|
val3 += TIMES_6785(coeff[14]);
|
|
val3 -= TIMES_39550(coeff[26]);
|
|
val3 -= TIMES_30270(coeff[24] + coeff[28]);
|
|
val3 += TIMES_12538(coeff[8] + coeff[12]);
|
|
|
|
t = (base + val1 + val2 + val3) >> 17;
|
|
out[8] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 - val2 + val3 - C4 + C16 + C20) >> 17;
|
|
out[15] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 + val2 - val3) >> 17;
|
|
out[16] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base + val1 - val2 - val3 - C4 + C20) >> 17;
|
|
out[23] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
|
|
//9,14,17,22
|
|
|
|
base = 0x1000000;
|
|
base += coeff[0] - coeff[4] - coeff[16] + coeff[20];
|
|
base += TIMES_12538(C2_18);
|
|
base -= TIMES_30270(C6_22);
|
|
|
|
val1 = TIMES_14743(coeff[9]);
|
|
val1 -= TIMES_3459(coeff[11]);
|
|
val1 -= TIMES_17391(coeff[13]);
|
|
val1 -= TIMES_9851(coeff[15]);
|
|
val1 -= TIMES_35594(coeff[25]);
|
|
val1 += TIMES_8351(coeff[27]);
|
|
val1 += TIMES_41986(coeff[29]);
|
|
val1 += TIMES_23783(coeff[31]);
|
|
|
|
val2 = TIMES_27242(C1_17);
|
|
val2 -= TIMES_6392(C3_19);
|
|
val2 -= TIMES_32134(C5_21);
|
|
val2 -= TIMES_18202(C7_23);
|
|
|
|
val3 = TIMES_6785(coeff[10]);
|
|
val3 -= TIMES_16382(coeff[14] + coeff[26]);
|
|
val3 += TIMES_39550(coeff[30]);
|
|
val3 += TIMES_12538(coeff[8] - coeff[12]);
|
|
val3 -= TIMES_30270(coeff[24] - coeff[28]);
|
|
|
|
t = (base + val1 + val2 + val3 + C4 + C16 - C20) >> 17;
|
|
out[9] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 - val2 + val3 + C16) >> 17;
|
|
out[14] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 + val2 - val3 + C4) >> 17;
|
|
out[17] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base + val1 - val2 - val3) >> 17;
|
|
out[22] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
|
|
//10,13,18,21
|
|
|
|
base = 0x1000000;
|
|
base += coeff[0] - coeff[4] - coeff[16] + coeff[20];
|
|
base -= TIMES_12538(C2_18);
|
|
base += TIMES_30270(C6_22);
|
|
|
|
val1 = TIMES_9851(coeff[9]);
|
|
val1 -= TIMES_17391(coeff[11]);
|
|
val1 += TIMES_3459(coeff[13]);
|
|
val1 += TIMES_14743(coeff[15]);
|
|
val1 -= TIMES_23783(coeff[25]);
|
|
val1 += TIMES_41986(coeff[27]);
|
|
val1 -= TIMES_8351(coeff[29]);
|
|
val1 -= TIMES_35594(coeff[31]);
|
|
|
|
val2 = TIMES_18202(C1_17);
|
|
val2 -= TIMES_32134(C3_19);
|
|
val2 += TIMES_6392(C5_21);
|
|
val2 += TIMES_27242(C7_23);
|
|
|
|
val3 = -TIMES_6785(coeff[10]);
|
|
val3 += TIMES_16382(coeff[14] + coeff[26]);
|
|
val3 -= TIMES_39550(coeff[30]);
|
|
val3 += TIMES_12538(coeff[8] - coeff[12]);
|
|
val3 -= TIMES_30270(coeff[24] - coeff[28]);
|
|
|
|
t = (base + val1 + val2 + val3) >> 17;
|
|
out[10] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 - val2 + val3 + C4 + C16 - C20) >> 17;
|
|
out[13] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 + val2 - val3) >> 17;
|
|
out[18] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base + val1 - val2 - val3 + C4) >> 17;
|
|
out[21] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
|
|
// 11,12,19,20
|
|
|
|
base = 0x1000000;
|
|
base += coeff[0] + coeff[4] - coeff[16] - coeff[20];
|
|
base -= TIMES_30270(C2_18);
|
|
base -= TIMES_12538(C6_22);
|
|
|
|
val1 = TIMES_3459(coeff[9]);
|
|
val1 -= TIMES_9851(coeff[11]);
|
|
val1 += TIMES_14743(coeff[13]);
|
|
val1 -= TIMES_8351(coeff[25]);
|
|
val1 += TIMES_23783(coeff[27]);
|
|
val1 -= TIMES_35594(coeff[29]);
|
|
|
|
val2 = TIMES_6392(C1_17);
|
|
val2 -= TIMES_18202(C3_19);
|
|
val2 += TIMES_27242(C5_21);
|
|
|
|
val3 = -TIMES_16382(coeff[10] - coeff[30]);
|
|
val3 -= TIMES_6785(coeff[14]);
|
|
val3 += TIMES_39550(coeff[26]);
|
|
val3 -= TIMES_30270(coeff[24] + coeff[28]);
|
|
val3 += TIMES_12538(coeff[8] + coeff[12]);
|
|
|
|
tmp1 = TIMES_32134(C7_23);
|
|
tmp2 = -TIMES_17391(coeff[15]) + TIMES_41986(coeff[31]);
|
|
|
|
t = (base + val1 + val2 + val3 - tmp1 + tmp2 + C16 + C20) >> 17;
|
|
out[11] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 - val2 + val3 + C16 + C20) >> 17;
|
|
out[12] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base - val1 + val2 - val3 - tmp1 - tmp2 - C4 + C20) >> 17;
|
|
out[19] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
t = (base + val1 - val2 - val3) >> 17;
|
|
out[20] = t & 0xFFFFFF00 ? t < 0 ? 0 : 255 : (unsigned char)t;
|
|
}
|
|
|
|
#undef TIMES_16382
|
|
#undef TIMES_23168
|
|
#undef TIMES_30270
|
|
#undef TIMES_41986
|
|
#undef TIMES_35594
|
|
#undef TIMES_23783
|
|
#undef TIMES_8351
|
|
#undef TIMES_17391
|
|
#undef TIMES_14743
|
|
#undef TIMES_9851
|
|
#undef TIMES_3459
|
|
#undef TIMES_32134
|
|
#undef TIMES_27242
|
|
#undef TIMES_18202
|
|
#undef TIMES_6392
|
|
#undef TIMES_39550
|
|
#undef TIMES_6785
|
|
#undef TIMES_12538
|
|
|
|
/******************************************************************************
|
|
* Main Decoder Functions
|
|
******************************************************************************/
|
|
|
|
/* This function handles the decompression of a single 8x4 block. It is
|
|
* independent of the palette (YUV422, YUV420, YUV400, GBR422...). cinfo->bytes
|
|
* determines the positin in the input buffer.
|
|
*/
|
|
static int
|
|
decompress8x4(unsigned char *pOut,
|
|
unsigned char *pIn,
|
|
int *lastDC,
|
|
int uvFlag,
|
|
struct comp_info *cinfo)
|
|
{
|
|
int i, x, y, dc;
|
|
int coeffs[32];
|
|
int deZigZag[32];
|
|
int *dest;
|
|
int *src;
|
|
unsigned char *qt = cinfo->qt;
|
|
|
|
if (!uvFlag) {
|
|
huffmanDecoderY(coeffs, (int *)pIn, cinfo);
|
|
|
|
/* iDPCM and dequantize first coefficient */
|
|
dc = (*lastDC) + coeffs[0];
|
|
coeffs[0] = dc * (qt[0] + 1);
|
|
*lastDC = dc;
|
|
|
|
/* ...and the second coefficient */
|
|
coeffs[1] = ((qt[1] + 1) * coeffs[1]) >> 1;
|
|
|
|
/* Dequantize, starting at 3rd element */
|
|
for (i = 2; i < 32; i++)
|
|
coeffs[i] = (qt[i] + 1) * coeffs[i];
|
|
} else {
|
|
huffmanDecoderUV(coeffs, (int *)pIn, cinfo);
|
|
|
|
/* iDPCM */
|
|
dc = (*lastDC) + coeffs[0];
|
|
coeffs[0] = dc;
|
|
*lastDC = dc;
|
|
|
|
/* Dequantize */
|
|
for (i = 0; i < 32; i++)
|
|
coeffs[i] = (qt[32 + i] + 1) * coeffs[i];
|
|
}
|
|
|
|
/* Dezigzag */
|
|
for (i = 0; i < 32; i++)
|
|
deZigZag[i] = coeffs[ZigZag518[i]];
|
|
|
|
/* Transpose the dezigzagged coefficient matrix */
|
|
src = deZigZag;
|
|
dest = coeffs;
|
|
for (y = 0; y <= 3; ++y) {
|
|
for (x = 0; x <= 7; ++x)
|
|
dest[x] = src[x * 4];
|
|
src += 1;
|
|
dest += 8;
|
|
}
|
|
|
|
/* Do the inverse DCT transform */
|
|
DCT_8x4(coeffs, pOut);
|
|
|
|
return 0; /* Always returns 0 */
|
|
}
|
|
|
|
static inline void
|
|
copyBlock(unsigned char *src, unsigned char *dest, int destInc)
|
|
{
|
|
int i;
|
|
unsigned int *pSrc, *pDest;
|
|
|
|
for (i = 0; i <= 3; i++) {
|
|
pSrc = (unsigned int *) src;
|
|
pDest = (unsigned int *) dest;
|
|
pDest[0] = pSrc[0];
|
|
pDest[1] = pSrc[1];
|
|
src += 8;
|
|
dest += destInc;
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
static inline int
|
|
decompress400NoMMXOV518(unsigned char *pIn,
|
|
unsigned char *pOut,
|
|
unsigned char *pTmp,
|
|
const int w,
|
|
const int h,
|
|
const int numpix,
|
|
struct comp_info *cinfo)
|
|
{
|
|
int iOutY, x, y;
|
|
int lastYDC = 0;
|
|
|
|
/* Start Y loop */
|
|
y = 0;
|
|
do {
|
|
iOutY = w * y;
|
|
x = 0;
|
|
do {
|
|
decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo);
|
|
copyBlock(pTmp, pOut + iOutY, w);
|
|
iOutY += 8;
|
|
x += 8;
|
|
} while (x < w);
|
|
y += 4;
|
|
} while (y < h);
|
|
|
|
/* Did we decode too much? */
|
|
if (cinfo->bytes > cinfo->rawLen + 897)
|
|
return 1;
|
|
|
|
/* Did we decode enough? */
|
|
if (cinfo->bytes >= cinfo->rawLen - 897)
|
|
return 0;
|
|
else
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
static inline int
|
|
decompress420NoMMXOV518(unsigned char *pIn,
|
|
unsigned char *pOut,
|
|
unsigned char *pTmp,
|
|
const int w,
|
|
const int h,
|
|
const int numpix,
|
|
struct comp_info *cinfo,
|
|
int yvu)
|
|
{
|
|
unsigned char *pOutU, *pOutV;
|
|
int iOutY, iOutU, iOutV, x, y;
|
|
int lastYDC = 0;
|
|
int lastUDC = 0;
|
|
int lastVDC = 0;
|
|
|
|
if (yvu) {
|
|
pOutV = pOut + numpix;
|
|
pOutU = pOutV + numpix / 4;
|
|
} else {
|
|
pOutU = pOut + numpix;
|
|
pOutV = pOutU + numpix / 4;
|
|
}
|
|
|
|
/* Start Y loop */
|
|
y = 0;
|
|
do {
|
|
iOutY = w * y;
|
|
iOutV = iOutU = iOutY / 4;
|
|
|
|
x = 0;
|
|
do {
|
|
decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo);
|
|
copyBlock(pTmp, pOut + iOutY, w);
|
|
iOutY += 8;
|
|
x += 8;
|
|
} while (x < w);
|
|
|
|
|
|
|
|
iOutY = w * (y + 4);
|
|
x = 0;
|
|
do {
|
|
decompress8x4(pTmp, pIn, &lastUDC, 1, cinfo);
|
|
copyBlock(pTmp, pOutU + iOutU, w/2);
|
|
iOutU += 8;
|
|
|
|
decompress8x4(pTmp, pIn, &lastVDC, 1, cinfo);
|
|
copyBlock(pTmp, pOutV + iOutV, w/2);
|
|
iOutV += 8;
|
|
|
|
decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo);
|
|
copyBlock(pTmp, pOut + iOutY, w);
|
|
iOutY += 8;
|
|
|
|
decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo);
|
|
copyBlock(pTmp, pOut + iOutY, w);
|
|
iOutY += 8;
|
|
|
|
x += 16;
|
|
} while (x < w);
|
|
|
|
y += 8;
|
|
} while (y < h);
|
|
|
|
/* Did we decode too much? */
|
|
if (cinfo->bytes > cinfo->rawLen + 897)
|
|
return 1;
|
|
|
|
/* Did we decode enough? */
|
|
if (cinfo->bytes >= cinfo->rawLen - (897 + 64))
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* Get quantization tables from input
|
|
* Returns: <0 if error, or >=0 otherwise */
|
|
static int
|
|
get_qt_dynamic(unsigned char *pIn, struct comp_info *cinfo)
|
|
{
|
|
int rawLen = cinfo->rawLen;
|
|
|
|
/* Make sure input is actually big enough to hold trailer */
|
|
if (rawLen < 72)
|
|
return -1;
|
|
|
|
cinfo->qt = pIn + rawLen - 64;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Remove all 0 blocks from input */
|
|
static void remove0blocks(unsigned char *pIn, int *inSize)
|
|
{
|
|
long long *in = (long long *)pIn;
|
|
long long *out = (long long *)pIn;
|
|
int i;
|
|
|
|
for (i = 0; i < *inSize; i += 8, in++)
|
|
/* Skip 8 byte blocks of all 0 */
|
|
if (*in)
|
|
*out++ = *in;
|
|
|
|
*inSize -= (in - out) * 8;
|
|
}
|
|
|
|
#if 0 /* not used */
|
|
/* Input format is raw isoc. data (with intact SOF header, packet numbers
|
|
* stripped, and all-zero blocks removed).
|
|
* Output format is planar YUV400
|
|
* Returns uncompressed data length if success, or zero if error
|
|
*/
|
|
static int
|
|
Decompress400(unsigned char *pIn,
|
|
unsigned char *pOut,
|
|
int w,
|
|
int h,
|
|
int inSize)
|
|
{
|
|
struct comp_info cinfo;
|
|
int numpix = w * h;
|
|
unsigned char pTmp[32];
|
|
|
|
remove0blocks(pIn, &inSize);
|
|
|
|
cinfo.bytes = 0;
|
|
cinfo.bits = 0;
|
|
cinfo.rawLen = inSize;
|
|
|
|
if (get_qt_dynamic(pIn, &cinfo) < 0)
|
|
return 0;
|
|
|
|
/* Decompress, skipping the 8-byte SOF header */
|
|
if (decompress400NoMMXOV518(pIn + 8, pOut, pTmp, w, h, numpix, &cinfo))
|
|
/* return 0; */
|
|
; /* Don't return error yet */
|
|
|
|
return numpix;
|
|
}
|
|
#endif
|
|
|
|
/* Input format is raw isoc. data (with intact SOF header, packet numbers
|
|
* stripped, and all-zero blocks removed).
|
|
* Output format is planar YUV420
|
|
* Returns uncompressed data length if success, or zero if error
|
|
*/
|
|
static int v4lconvert_ov518_to_yuv420(unsigned char *src, unsigned char *dst,
|
|
int w, int h, int yvu, int inSize)
|
|
{
|
|
struct comp_info cinfo;
|
|
int numpix = w * h;
|
|
unsigned char pTmp[32];
|
|
|
|
remove0blocks(src, &inSize);
|
|
|
|
cinfo.bytes = 0;
|
|
cinfo.bits = 0;
|
|
cinfo.rawLen = inSize;
|
|
|
|
if (get_qt_dynamic(src, &cinfo) < 0)
|
|
return -1;
|
|
|
|
/* Decompress, skipping the 8-byte SOF header */
|
|
if (decompress420NoMMXOV518(src + 8, dst, pTmp, w, h, numpix, &cinfo, yvu))
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int width, height, yvu, src_size, dest_size;
|
|
unsigned char src_buf[200000];
|
|
unsigned char dest_buf[500000];
|
|
|
|
while (1) {
|
|
if (v4lconvert_helper_read(STDIN_FILENO, &width, sizeof(int), argv[0]))
|
|
return 1; /* Erm, no way to recover without loosing sync with libv4l */
|
|
|
|
if (v4lconvert_helper_read(STDIN_FILENO, &height, sizeof(int), argv[0]))
|
|
return 1; /* Erm, no way to recover without loosing sync with libv4l */
|
|
|
|
if (v4lconvert_helper_read(STDIN_FILENO, &yvu, sizeof(int), argv[0]))
|
|
return 1; /* Erm, no way to recover without loosing sync with libv4l */
|
|
|
|
if (v4lconvert_helper_read(STDIN_FILENO, &src_size, sizeof(int), argv[0]))
|
|
return 1; /* Erm, no way to recover without loosing sync with libv4l */
|
|
|
|
if (src_size > sizeof(src_buf)) {
|
|
fprintf(stderr, "%s: error: src_buf too small, need: %d\n",
|
|
argv[0], src_size);
|
|
return 2;
|
|
}
|
|
|
|
if (v4lconvert_helper_read(STDIN_FILENO, src_buf, src_size, argv[0]))
|
|
return 1; /* Erm, no way to recover without loosing sync with libv4l */
|
|
|
|
|
|
dest_size = width * height * 3 / 2;
|
|
if (width <= 0 || width > SHRT_MAX || height <= 0 || height > SHRT_MAX) {
|
|
fprintf(stderr, "%s: error: width or height out of bounds\n",
|
|
argv[0]);
|
|
dest_size = -1;
|
|
} else if (dest_size > sizeof(dest_buf)) {
|
|
fprintf(stderr, "%s: error: dest_buf too small, need: %d\n",
|
|
argv[0], dest_size);
|
|
dest_size = -1;
|
|
} else if (v4lconvert_ov518_to_yuv420(src_buf, dest_buf, width, height,
|
|
yvu, src_size))
|
|
dest_size = -1;
|
|
|
|
if (v4lconvert_helper_write(STDOUT_FILENO, &dest_size, sizeof(int),
|
|
argv[0]))
|
|
return 1; /* Erm, no way to recover without loosing sync with libv4l */
|
|
|
|
if (dest_size == -1)
|
|
continue;
|
|
|
|
if (v4lconvert_helper_write(STDOUT_FILENO, dest_buf, dest_size, argv[0]))
|
|
return 1; /* Erm, no way to recover without loosing sync with libv4l */
|
|
}
|
|
}
|