コード例 #1
0
/** Documented at declaration */
int
gpujpeg_table_huffman_decoder_init(struct gpujpeg_table_huffman_decoder* table, struct gpujpeg_table_huffman_decoder* d_table, enum gpujpeg_component_type comp_type, enum gpujpeg_huffman_type huff_type)
{
    assert(comp_type == GPUJPEG_COMPONENT_LUMINANCE || comp_type == GPUJPEG_COMPONENT_CHROMINANCE);
    assert(huff_type == GPUJPEG_HUFFMAN_DC || huff_type == GPUJPEG_HUFFMAN_AC);
    if ( comp_type == GPUJPEG_COMPONENT_LUMINANCE ) {
        if ( huff_type == GPUJPEG_HUFFMAN_DC ) {
            memcpy(table->bits, gpujpeg_table_huffman_y_dc_bits, sizeof(table->bits));
            memcpy(table->huffval, gpujpeg_table_huffman_y_dc_value, sizeof(table->huffval));
        } else {
            memcpy(table->bits, gpujpeg_table_huffman_y_ac_bits, sizeof(table->bits));
            memcpy(table->huffval, gpujpeg_table_huffman_y_ac_value, sizeof(table->huffval));
        }        
    } else if ( comp_type == GPUJPEG_COMPONENT_CHROMINANCE ) {
        if ( huff_type == GPUJPEG_HUFFMAN_DC ) {
            memcpy(table->bits, gpujpeg_table_huffman_cbcr_dc_bits, sizeof(table->bits));
            memcpy(table->huffval, gpujpeg_table_huffman_cbcr_dc_value, sizeof(table->huffval));
        } else {
            memcpy(table->bits, gpujpeg_table_huffman_cbcr_ac_bits, sizeof(table->bits));
            memcpy(table->huffval, gpujpeg_table_huffman_cbcr_ac_value, sizeof(table->huffval));
        }
    }
    gpujpeg_table_huffman_decoder_compute(table, d_table);
        
    return 0;
}
コード例 #2
0
/**
 * Read huffman table definition block from image
 * 
 * @param decoder
 * @param image
 * @return 0 if succeeds, otherwise nonzero
 */
int
gpujpeg_reader_read_dht(struct gpujpeg_decoder* decoder, uint8_t** image)
{    
    int length = (int)gpujpeg_reader_read_2byte(*image);
    length -= 2;
    
    int index = gpujpeg_reader_read_byte(*image);
    struct gpujpeg_table_huffman_decoder* table = NULL;
    struct gpujpeg_table_huffman_decoder* d_table = NULL;
    switch(index) {
    case 0:
        table = &decoder->table_huffman[GPUJPEG_COMPONENT_LUMINANCE][GPUJPEG_HUFFMAN_DC];
        d_table = decoder->d_table_huffman[GPUJPEG_COMPONENT_LUMINANCE][GPUJPEG_HUFFMAN_DC];
        break;
    case 16:
        table = &decoder->table_huffman[GPUJPEG_COMPONENT_LUMINANCE][GPUJPEG_HUFFMAN_AC];
        d_table = decoder->d_table_huffman[GPUJPEG_COMPONENT_LUMINANCE][GPUJPEG_HUFFMAN_AC];
        break;
    case 1:
        table = &decoder->table_huffman[GPUJPEG_COMPONENT_CHROMINANCE][GPUJPEG_HUFFMAN_DC];
        d_table = decoder->d_table_huffman[GPUJPEG_COMPONENT_CHROMINANCE][GPUJPEG_HUFFMAN_DC];
        break;
    case 17:
        table = &decoder->table_huffman[GPUJPEG_COMPONENT_CHROMINANCE][GPUJPEG_HUFFMAN_AC];
        d_table = decoder->d_table_huffman[GPUJPEG_COMPONENT_CHROMINANCE][GPUJPEG_HUFFMAN_AC];
        break;
    default:
        fprintf(stderr, "[GPUJPEG] [Error] DHT marker index should be 0, 1, 16 or 17 but %d was presented!\n", index);
        return -1;
    }
    length -= 1;
    
    // Read in bits[]
    table->bits[0] = 0;
    int count = 0;
    for ( int i = 1; i <= 16; i++ ) {
        table->bits[i] = gpujpeg_reader_read_byte(*image);
        count += table->bits[i];
        if ( length > 0 ) {
            length--;
        } else {
            fprintf(stderr, "[GPUJPEG] [Error] DHT marker unexpected end when reading bit counts!\n", index);
            return -1;
        }
    }   

    // Read in huffval
    for ( int i = 0; i < count; i++ ){
        table->huffval[i] = gpujpeg_reader_read_byte(*image);
        if ( length > 0 ) {
            length--;
        } else {
            fprintf(stderr, "[GPUJPEG] [Error] DHT marker unexpected end when reading huffman values!\n", index);
            return -1;
        }
    }
    
    // Check length
    if ( length > 0 ) {
        fprintf(stderr, "[GPUJPEG] [Warning] DHT marker contains %d more bytes than needed!\n", length);
        *image += length;
    }
    
    // Compute huffman table for read values
    gpujpeg_table_huffman_decoder_compute(table, d_table);
    
    return 0;
}