1*dfc6aa5cSAndroid Build Coastguard Worker /* 2*dfc6aa5cSAndroid Build Coastguard Worker * jchuff.h 3*dfc6aa5cSAndroid Build Coastguard Worker * 4*dfc6aa5cSAndroid Build Coastguard Worker * This file was part of the Independent JPEG Group's software: 5*dfc6aa5cSAndroid Build Coastguard Worker * Copyright (C) 1991-1997, Thomas G. Lane. 6*dfc6aa5cSAndroid Build Coastguard Worker * libjpeg-turbo Modifications: 7*dfc6aa5cSAndroid Build Coastguard Worker * Copyright (C) 2009, 2018, 2021, D. R. Commander. 8*dfc6aa5cSAndroid Build Coastguard Worker * Copyright (C) 2018, Matthias Räncker. 9*dfc6aa5cSAndroid Build Coastguard Worker * Copyright (C) 2020-2021, Arm Limited. 10*dfc6aa5cSAndroid Build Coastguard Worker * For conditions of distribution and use, see the accompanying README.ijg 11*dfc6aa5cSAndroid Build Coastguard Worker * file. 12*dfc6aa5cSAndroid Build Coastguard Worker */ 13*dfc6aa5cSAndroid Build Coastguard Worker 14*dfc6aa5cSAndroid Build Coastguard Worker /* Expanded entropy encoder object for Huffman encoding. 15*dfc6aa5cSAndroid Build Coastguard Worker * 16*dfc6aa5cSAndroid Build Coastguard Worker * The savable_state subrecord contains fields that change within an MCU, 17*dfc6aa5cSAndroid Build Coastguard Worker * but must not be updated permanently until we complete the MCU. 18*dfc6aa5cSAndroid Build Coastguard Worker */ 19*dfc6aa5cSAndroid Build Coastguard Worker 20*dfc6aa5cSAndroid Build Coastguard Worker #if defined(__aarch64__) || defined(_M_ARM64) 21*dfc6aa5cSAndroid Build Coastguard Worker #define BIT_BUF_SIZE 64 22*dfc6aa5cSAndroid Build Coastguard Worker #else 23*dfc6aa5cSAndroid Build Coastguard Worker #define BIT_BUF_SIZE 32 24*dfc6aa5cSAndroid Build Coastguard Worker #endif 25*dfc6aa5cSAndroid Build Coastguard Worker 26*dfc6aa5cSAndroid Build Coastguard Worker typedef struct { 27*dfc6aa5cSAndroid Build Coastguard Worker size_t put_buffer; /* current bit accumulation buffer */ 28*dfc6aa5cSAndroid Build Coastguard Worker int free_bits; /* # of bits available in it */ 29*dfc6aa5cSAndroid Build Coastguard Worker int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ 30*dfc6aa5cSAndroid Build Coastguard Worker } savable_state; 31*dfc6aa5cSAndroid Build Coastguard Worker 32*dfc6aa5cSAndroid Build Coastguard Worker typedef struct { 33*dfc6aa5cSAndroid Build Coastguard Worker JOCTET *next_output_byte; /* => next byte to write in buffer */ 34*dfc6aa5cSAndroid Build Coastguard Worker size_t free_in_buffer; /* # of byte spaces remaining in buffer */ 35*dfc6aa5cSAndroid Build Coastguard Worker savable_state cur; /* Current bit buffer & DC state */ 36*dfc6aa5cSAndroid Build Coastguard Worker j_compress_ptr cinfo; /* dump_buffer needs access to this */ 37*dfc6aa5cSAndroid Build Coastguard Worker int simd; 38*dfc6aa5cSAndroid Build Coastguard Worker } working_state; 39*dfc6aa5cSAndroid Build Coastguard Worker 40*dfc6aa5cSAndroid Build Coastguard Worker /* Outputting bits to the file */ 41*dfc6aa5cSAndroid Build Coastguard Worker 42*dfc6aa5cSAndroid Build Coastguard Worker /* Output byte b and, speculatively, an additional 0 byte. 0xFF must be encoded 43*dfc6aa5cSAndroid Build Coastguard Worker * as 0xFF 0x00, so the output buffer pointer is advanced by 2 if the byte is 44*dfc6aa5cSAndroid Build Coastguard Worker * 0xFF. Otherwise, the output buffer pointer is advanced by 1, and the 45*dfc6aa5cSAndroid Build Coastguard Worker * speculative 0 byte will be overwritten by the next byte. 46*dfc6aa5cSAndroid Build Coastguard Worker */ 47*dfc6aa5cSAndroid Build Coastguard Worker #define EMIT_BYTE(b) { \ 48*dfc6aa5cSAndroid Build Coastguard Worker buffer[0] = (JOCTET)(b); \ 49*dfc6aa5cSAndroid Build Coastguard Worker buffer[1] = 0; \ 50*dfc6aa5cSAndroid Build Coastguard Worker buffer -= -2 + ((JOCTET)(b) < 0xFF); \ 51*dfc6aa5cSAndroid Build Coastguard Worker } 52*dfc6aa5cSAndroid Build Coastguard Worker 53*dfc6aa5cSAndroid Build Coastguard Worker /* Output the entire bit buffer. If there are no 0xFF bytes in it, then write 54*dfc6aa5cSAndroid Build Coastguard Worker * directly to the output buffer. Otherwise, use the EMIT_BYTE() macro to 55*dfc6aa5cSAndroid Build Coastguard Worker * encode 0xFF as 0xFF 0x00. 56*dfc6aa5cSAndroid Build Coastguard Worker */ 57*dfc6aa5cSAndroid Build Coastguard Worker #if defined(__aarch64__) || defined(_M_ARM64) 58*dfc6aa5cSAndroid Build Coastguard Worker 59*dfc6aa5cSAndroid Build Coastguard Worker #define FLUSH() { \ 60*dfc6aa5cSAndroid Build Coastguard Worker if (put_buffer & 0x8080808080808080 & ~(put_buffer + 0x0101010101010101)) { \ 61*dfc6aa5cSAndroid Build Coastguard Worker EMIT_BYTE(put_buffer >> 56) \ 62*dfc6aa5cSAndroid Build Coastguard Worker EMIT_BYTE(put_buffer >> 48) \ 63*dfc6aa5cSAndroid Build Coastguard Worker EMIT_BYTE(put_buffer >> 40) \ 64*dfc6aa5cSAndroid Build Coastguard Worker EMIT_BYTE(put_buffer >> 32) \ 65*dfc6aa5cSAndroid Build Coastguard Worker EMIT_BYTE(put_buffer >> 24) \ 66*dfc6aa5cSAndroid Build Coastguard Worker EMIT_BYTE(put_buffer >> 16) \ 67*dfc6aa5cSAndroid Build Coastguard Worker EMIT_BYTE(put_buffer >> 8) \ 68*dfc6aa5cSAndroid Build Coastguard Worker EMIT_BYTE(put_buffer ) \ 69*dfc6aa5cSAndroid Build Coastguard Worker } else { \ 70*dfc6aa5cSAndroid Build Coastguard Worker *((uint64_t *)buffer) = BUILTIN_BSWAP64(put_buffer); \ 71*dfc6aa5cSAndroid Build Coastguard Worker buffer += 8; \ 72*dfc6aa5cSAndroid Build Coastguard Worker } \ 73*dfc6aa5cSAndroid Build Coastguard Worker } 74*dfc6aa5cSAndroid Build Coastguard Worker 75*dfc6aa5cSAndroid Build Coastguard Worker #else 76*dfc6aa5cSAndroid Build Coastguard Worker 77*dfc6aa5cSAndroid Build Coastguard Worker #if defined(_MSC_VER) && !defined(__clang__) 78*dfc6aa5cSAndroid Build Coastguard Worker #define SPLAT() { \ 79*dfc6aa5cSAndroid Build Coastguard Worker buffer[0] = (JOCTET)(put_buffer >> 24); \ 80*dfc6aa5cSAndroid Build Coastguard Worker buffer[1] = (JOCTET)(put_buffer >> 16); \ 81*dfc6aa5cSAndroid Build Coastguard Worker buffer[2] = (JOCTET)(put_buffer >> 8); \ 82*dfc6aa5cSAndroid Build Coastguard Worker buffer[3] = (JOCTET)(put_buffer ); \ 83*dfc6aa5cSAndroid Build Coastguard Worker buffer += 4; \ 84*dfc6aa5cSAndroid Build Coastguard Worker } 85*dfc6aa5cSAndroid Build Coastguard Worker #else 86*dfc6aa5cSAndroid Build Coastguard Worker #define SPLAT() { \ 87*dfc6aa5cSAndroid Build Coastguard Worker put_buffer = __builtin_bswap32(put_buffer); \ 88*dfc6aa5cSAndroid Build Coastguard Worker __asm__("str %1, [%0], #4" : "+r" (buffer) : "r" (put_buffer)); \ 89*dfc6aa5cSAndroid Build Coastguard Worker } 90*dfc6aa5cSAndroid Build Coastguard Worker #endif 91*dfc6aa5cSAndroid Build Coastguard Worker 92*dfc6aa5cSAndroid Build Coastguard Worker #define FLUSH() { \ 93*dfc6aa5cSAndroid Build Coastguard Worker if (put_buffer & 0x80808080 & ~(put_buffer + 0x01010101)) { \ 94*dfc6aa5cSAndroid Build Coastguard Worker EMIT_BYTE(put_buffer >> 24) \ 95*dfc6aa5cSAndroid Build Coastguard Worker EMIT_BYTE(put_buffer >> 16) \ 96*dfc6aa5cSAndroid Build Coastguard Worker EMIT_BYTE(put_buffer >> 8) \ 97*dfc6aa5cSAndroid Build Coastguard Worker EMIT_BYTE(put_buffer ) \ 98*dfc6aa5cSAndroid Build Coastguard Worker } else { \ 99*dfc6aa5cSAndroid Build Coastguard Worker SPLAT(); \ 100*dfc6aa5cSAndroid Build Coastguard Worker } \ 101*dfc6aa5cSAndroid Build Coastguard Worker } 102*dfc6aa5cSAndroid Build Coastguard Worker 103*dfc6aa5cSAndroid Build Coastguard Worker #endif 104*dfc6aa5cSAndroid Build Coastguard Worker 105*dfc6aa5cSAndroid Build Coastguard Worker /* Fill the bit buffer to capacity with the leading bits from code, then output 106*dfc6aa5cSAndroid Build Coastguard Worker * the bit buffer and put the remaining bits from code into the bit buffer. 107*dfc6aa5cSAndroid Build Coastguard Worker */ 108*dfc6aa5cSAndroid Build Coastguard Worker #define PUT_AND_FLUSH(code, size) { \ 109*dfc6aa5cSAndroid Build Coastguard Worker put_buffer = (put_buffer << (size + free_bits)) | (code >> -free_bits); \ 110*dfc6aa5cSAndroid Build Coastguard Worker FLUSH() \ 111*dfc6aa5cSAndroid Build Coastguard Worker free_bits += BIT_BUF_SIZE; \ 112*dfc6aa5cSAndroid Build Coastguard Worker put_buffer = code; \ 113*dfc6aa5cSAndroid Build Coastguard Worker } 114*dfc6aa5cSAndroid Build Coastguard Worker 115*dfc6aa5cSAndroid Build Coastguard Worker /* Insert code into the bit buffer and output the bit buffer if needed. 116*dfc6aa5cSAndroid Build Coastguard Worker * NOTE: We can't flush with free_bits == 0, since the left shift in 117*dfc6aa5cSAndroid Build Coastguard Worker * PUT_AND_FLUSH() would have undefined behavior. 118*dfc6aa5cSAndroid Build Coastguard Worker */ 119*dfc6aa5cSAndroid Build Coastguard Worker #define PUT_BITS(code, size) { \ 120*dfc6aa5cSAndroid Build Coastguard Worker free_bits -= size; \ 121*dfc6aa5cSAndroid Build Coastguard Worker if (free_bits < 0) \ 122*dfc6aa5cSAndroid Build Coastguard Worker PUT_AND_FLUSH(code, size) \ 123*dfc6aa5cSAndroid Build Coastguard Worker else \ 124*dfc6aa5cSAndroid Build Coastguard Worker put_buffer = (put_buffer << size) | code; \ 125*dfc6aa5cSAndroid Build Coastguard Worker } 126*dfc6aa5cSAndroid Build Coastguard Worker 127*dfc6aa5cSAndroid Build Coastguard Worker #define PUT_CODE(code, size, diff) { \ 128*dfc6aa5cSAndroid Build Coastguard Worker diff |= code << nbits; \ 129*dfc6aa5cSAndroid Build Coastguard Worker nbits += size; \ 130*dfc6aa5cSAndroid Build Coastguard Worker PUT_BITS(diff, nbits) \ 131*dfc6aa5cSAndroid Build Coastguard Worker } 132