Example #1
0
static int jpeg_create_header(uint8_t *buf, int size, uint32_t type, uint32_t w,
                              uint32_t h, const uint8_t *qtable, int nb_qtable,
                              int dri)
{
    PutByteContext pbc;
    uint8_t *dht_size_ptr;
    int dht_size, i;

    bytestream2_init_writer(&pbc, buf, size);

    /* Convert from blocks to pixels. */
    w <<= 3;
    h <<= 3;

    /* SOI */
    jpeg_put_marker(&pbc, SOI);

    /* JFIF header */
    jpeg_put_marker(&pbc, APP0);
    bytestream2_put_be16(&pbc, 16);
    bytestream2_put_buffer(&pbc, "JFIF", 5);
    bytestream2_put_be16(&pbc, 0x0201);
    bytestream2_put_byte(&pbc, 0);
    bytestream2_put_be16(&pbc, 1);
    bytestream2_put_be16(&pbc, 1);
    bytestream2_put_byte(&pbc, 0);
    bytestream2_put_byte(&pbc, 0);

    if (dri) {
        jpeg_put_marker(&pbc, DRI);
        bytestream2_put_be16(&pbc, 4);
        bytestream2_put_be16(&pbc, dri);
    }

    /* DQT */
    jpeg_put_marker(&pbc, DQT);
    bytestream2_put_be16(&pbc, 2 + nb_qtable * (1 + 64));

    for (i = 0; i < nb_qtable; i++) {
        bytestream2_put_byte(&pbc, i);

        /* Each table is an array of 64 values given in zig-zag
         * order, identical to the format used in a JFIF DQT
         * marker segment. */
        bytestream2_put_buffer(&pbc, qtable + 64 * i, 64);
    }

    /* DHT */
    jpeg_put_marker(&pbc, DHT);
    dht_size_ptr = pbc.buffer;
    bytestream2_put_be16(&pbc, 0);

    dht_size  = 2;
    dht_size += jpeg_create_huffman_table(&pbc, 0, 0,avpriv_mjpeg_bits_dc_luminance,
                                          avpriv_mjpeg_val_dc);
    dht_size += jpeg_create_huffman_table(&pbc, 0, 1, avpriv_mjpeg_bits_dc_chrominance,
                                          avpriv_mjpeg_val_dc);
    dht_size += jpeg_create_huffman_table(&pbc, 1, 0, avpriv_mjpeg_bits_ac_luminance,
                                          avpriv_mjpeg_val_ac_luminance);
    dht_size += jpeg_create_huffman_table(&pbc, 1, 1, avpriv_mjpeg_bits_ac_chrominance,
                                          avpriv_mjpeg_val_ac_chrominance);
    AV_WB16(dht_size_ptr, dht_size);

    /* SOF0 */
    jpeg_put_marker(&pbc, SOF0);
    bytestream2_put_be16(&pbc, 17); /* size */
    bytestream2_put_byte(&pbc, 8); /* bits per component */
    bytestream2_put_be16(&pbc, h);
    bytestream2_put_be16(&pbc, w);
    bytestream2_put_byte(&pbc, 3); /* number of components */
    bytestream2_put_byte(&pbc, 1); /* component number */
    bytestream2_put_byte(&pbc, (2 << 4) | (type ? 2 : 1)); /* hsample/vsample */
    bytestream2_put_byte(&pbc, 0); /* matrix number */
    bytestream2_put_byte(&pbc, 2); /* component number */
    bytestream2_put_byte(&pbc, 1 << 4 | 1); /* hsample/vsample */
    bytestream2_put_byte(&pbc, nb_qtable == 2 ? 1 : 0); /* matrix number */
    bytestream2_put_byte(&pbc, 3); /* component number */
    bytestream2_put_byte(&pbc, 1 << 4 | 1); /* hsample/vsample */
    bytestream2_put_byte(&pbc, nb_qtable == 2 ? 1 : 0); /* matrix number */

    /* SOS */
    jpeg_put_marker(&pbc, SOS);
    bytestream2_put_be16(&pbc, 12);
    bytestream2_put_byte(&pbc, 3);
    bytestream2_put_byte(&pbc, 1);
    bytestream2_put_byte(&pbc, 0);
    bytestream2_put_byte(&pbc, 2);
    bytestream2_put_byte(&pbc, 17);
    bytestream2_put_byte(&pbc, 3);
    bytestream2_put_byte(&pbc, 17);
    bytestream2_put_byte(&pbc, 0);
    bytestream2_put_byte(&pbc, 63);
    bytestream2_put_byte(&pbc, 0);

    /* Return the length in bytes of the JPEG header. */
    return bytestream2_tell_p(&pbc);
}
Example #2
0
static int jpeg_create_header(uint8_t *buf, int size, uint32_t type, uint32_t w,
                              uint32_t h, const uint8_t *qtable, int nb_qtable)
{
    PutBitContext pbc;

    init_put_bits(&pbc, buf, size);

    /* Convert from blocks to pixels. */
    w <<= 3;
    h <<= 3;

    /* SOI */
    put_marker(&pbc, SOI);

    /* JFIF header */
    put_marker(&pbc, APP0);
    put_bits(&pbc, 16, 16);
    avpriv_put_string(&pbc, "JFIF", 1);
    put_bits(&pbc, 16, 0x0201);
    put_bits(&pbc, 8, 0);
    put_bits(&pbc, 16, 1);
    put_bits(&pbc, 16, 1);
    put_bits(&pbc, 8, 0);
    put_bits(&pbc, 8, 0);

    /* DQT */
    put_marker(&pbc, DQT);
    if (nb_qtable == 2) {
        put_bits(&pbc, 16, 2 + 2 * (1 + 64));
    } else {
        put_bits(&pbc, 16, 2 + 1 * (1 + 64));
    }
    put_bits(&pbc, 8, 0);

    /* Each table is an array of 64 values given in zig-zag
     * order, identical to the format used in a JFIF DQT
     * marker segment. */
    avpriv_copy_bits(&pbc, qtable, 64 * 8);

    if (nb_qtable == 2) {
        put_bits(&pbc, 8, 1);
        avpriv_copy_bits(&pbc, qtable + 64, 64 * 8);
    }

    /* DHT */
    put_marker(&pbc, DHT);

    jpeg_create_huffman_table(&pbc, 0, 0, avpriv_mjpeg_bits_dc_luminance,
                              avpriv_mjpeg_val_dc);
    jpeg_create_huffman_table(&pbc, 0, 1, avpriv_mjpeg_bits_dc_chrominance,
                              avpriv_mjpeg_val_dc);
    jpeg_create_huffman_table(&pbc, 1, 0, avpriv_mjpeg_bits_ac_luminance,
                              avpriv_mjpeg_val_ac_luminance);
    jpeg_create_huffman_table(&pbc, 1, 1, avpriv_mjpeg_bits_ac_chrominance,
                              avpriv_mjpeg_val_ac_chrominance);

    /* SOF0 */
    put_marker(&pbc, SOF0);
    put_bits(&pbc, 16, 17);
    put_bits(&pbc, 8, 8);
    put_bits(&pbc, 8, h >> 8);
    put_bits(&pbc, 8, h);
    put_bits(&pbc, 8, w >> 8);
    put_bits(&pbc, 8, w);
    put_bits(&pbc, 8, 3);
    put_bits(&pbc, 8, 1);
    put_bits(&pbc, 8, type ? 34 : 33);
    put_bits(&pbc, 8, 0);
    put_bits(&pbc, 8, 2);
    put_bits(&pbc, 8, 17);
    put_bits(&pbc, 8, nb_qtable == 2 ? 1 : 0);
    put_bits(&pbc, 8, 3);
    put_bits(&pbc, 8, 17);
    put_bits(&pbc, 8, nb_qtable == 2 ? 1 : 0);

    /* SOS */
    put_marker(&pbc, SOS);
    put_bits(&pbc, 16, 12);
    put_bits(&pbc, 8, 3);
    put_bits(&pbc, 8, 1);
    put_bits(&pbc, 8, 0);
    put_bits(&pbc, 8, 2);
    put_bits(&pbc, 8, 17);
    put_bits(&pbc, 8, 3);
    put_bits(&pbc, 8, 17);
    put_bits(&pbc, 8, 0);
    put_bits(&pbc, 8, 63);
    put_bits(&pbc, 8, 0);

    /* Fill the buffer. */
    flush_put_bits(&pbc);

    /* Return the length in bytes of the JPEG header. */
    return put_bits_count(&pbc) / 8;
}