Logo Search packages:      
Sourcecode: librasterlite version File versions  Download package

local int read_tc_header ( unsigned char *  buf,
int  buf_size,
eps_block_header hdr 
)

Read TRUECOLOR header

This function reads and checks block header of type EPS_TRUECOLOR_BLOCK. Result is stored in the hdr structure.

Note:
Structure hdr is undefined unless function returns EPS_OK.
Parameters:
bufData buffer
buf_sizeBuffer size
hdrBlock header
Returns:
Either EPS_OK or EPS_PARAM_ERROR or EPS_FORMAT_ERROR

Definition at line 337 of file libmain.c.

References tc_hdr_tag::Cb_rt, eps_block_header_tag::chk, eps_block_header_tag::chk_flag, tc_hdr_tag::Cr_rt, eps_block_header_tag::crc, eps_block_header_tag::crc_flag, eps_block_header_tag::data_size, tc_hdr_tag::dc_Cb, tc_hdr_tag::dc_Cr, tc_hdr_tag::dc_Y, EPS_BAD_CRC, EPS_FORMAT_ERROR, EPS_GOOD_CRC, EPS_MAX_BLOCK_SIZE, EPS_MODE_NORMAL, EPS_MODE_OTLPF, EPS_OK, EPS_PARAM_ERROR, EPS_RESAMPLE_420, EPS_RESAMPLE_444, tc_hdr_tag::fb_id, get_fb(), tc_hdr_tag::h, tc_hdr_tag::H, eps_block_header_tag::hdr_size, header_sanity_check(), filterbank_t_tag::id, tc_hdr_tag::mode, ORTHOGONAL, tc_hdr_tag::resample, eps_block_header_tag::tc, terminate_header(), filterbank_t_tag::type, unterminate_header(), tc_hdr_tag::w, tc_hdr_tag::W, tc_hdr_tag::x, tc_hdr_tag::y, and tc_hdr_tag::Y_rt.

Referenced by eps_read_block_header().

{
    filterbank_t *fb;

    char fb_id[32];

    crc32_t hdr_crc;
    crc32_t data_crc;

    int result;
    int len;
    int n;

    char *chk_pos;
    char *str;
    /* Sanity checks */
    if (!buf || !hdr) {
        return EPS_PARAM_ERROR;
    }

    if (buf_size < 1) {
        return EPS_PARAM_ERROR;
    }

    /* Terminate header for ease of processing */
    if (terminate_header(buf, buf_size, 14) != EPS_OK) {
        return EPS_FORMAT_ERROR;
    }

    /* Check for maliciuos symbols */
    if (header_sanity_check(buf) != EPS_OK) {
        unterminate_header(buf);
        return EPS_FORMAT_ERROR;
    }

    /* Handle header as a regular null-terminated string */
    str = (char *) buf;
    len = strlen(str);

    /* Mark the position of header CRC field */
    chk_pos = strstr(str, "chk=");
    /* Parse header fields */
    result = sscanf(str,
        "type=tc;W=%d;H=%d;w=%d;h=%d;x=%d;y=%d;m=%d;"
        "r=%d;dc=%d:%d:%d;rt=%d:%d:%d;fb=%31[a-z0-9];"
        "chk=%x;crc=%x%n",
        &hdr->tc.W, &hdr->tc.H, &hdr->tc.w, &hdr->tc.h,
        &hdr->tc.x, &hdr->tc.y, &hdr->tc.mode, &hdr->tc.resample,
        &hdr->tc.dc_Y, &hdr->tc.dc_Cb, &hdr->tc.dc_Cr,
        &hdr->tc.Y_rt, &hdr->tc.Cb_rt, &hdr->tc.Cr_rt,
        fb_id, &hdr->chk, &hdr->crc, &n);
    unterminate_header(buf);

    /* Check for parsing errors (see also sscanf(3)) */
    if ((result < 17) || (n != len)) {
        return EPS_FORMAT_ERROR;
    }

    /* Compute header & data size */
    hdr->hdr_size = len + 1;
    hdr->data_size = buf_size - hdr->hdr_size;

    /* Sanity checks */
    assert(hdr->data_size >= 0);
    assert(hdr->hdr_size + hdr->data_size == buf_size);

    /* Check transform mode */
    if ((hdr->tc.mode != EPS_MODE_NORMAL) && (hdr->tc.mode != EPS_MODE_OTLPF)) {
        return EPS_FORMAT_ERROR;
    }

    /* Check image (W, H) and block (w, y, w, h) parameters for consistency */
    if ((hdr->tc.W <= 0) || (hdr->tc.H <= 0)) {
        return EPS_FORMAT_ERROR;
    }

    if ((hdr->tc.w < 1) || (hdr->tc.h < 1)) {
        return EPS_FORMAT_ERROR;
    }

    if (hdr->tc.w > EPS_MAX_BLOCK_SIZE + hdr->tc.mode == EPS_MODE_OTLPF) {
        return EPS_FORMAT_ERROR;
    }

    if (hdr->tc.h > EPS_MAX_BLOCK_SIZE + hdr->tc.mode == EPS_MODE_OTLPF) {
        return EPS_FORMAT_ERROR;
    }

    if ((hdr->tc.x < 0) || (hdr->tc.y < 0)) {
        return EPS_FORMAT_ERROR;
    }

    if (hdr->tc.x + hdr->tc.w > hdr->tc.W) {
        return EPS_FORMAT_ERROR;
    }

    if (hdr->tc.y + hdr->tc.h > hdr->tc.H) {
        return EPS_FORMAT_ERROR;
    }

    /* Check resampling mode */
    if ((hdr->tc.resample != EPS_RESAMPLE_444) &&
        (hdr->tc.resample != EPS_RESAMPLE_420))
    {
        return EPS_FORMAT_ERROR;
    }

    /* Check DC level for Y, Cb and Cr channels */
    if ((hdr->tc.dc_Y < 0) || (hdr->tc.dc_Y > 255)) {
        return EPS_FORMAT_ERROR;
    }

    if ((hdr->tc.dc_Cb < 0) || (hdr->tc.dc_Cb > 255)) {
        return EPS_FORMAT_ERROR;
    }

    if ((hdr->tc.dc_Cr < 0) || (hdr->tc.dc_Cr > 255)) {
        return EPS_FORMAT_ERROR;
    }

    if ((hdr->tc.Y_rt <= 0) || (hdr->tc.Cb_rt <= 0) || (hdr->tc.Cr_rt <= 0)) {
        return EPS_FORMAT_ERROR;
    }

    /* Find filterbank by id */
    if (fb = get_fb(fb_id)) {
        hdr->tc.fb_id = fb->id;
    } else {
        hdr->tc.fb_id = NULL;
    }

    /* EPS_MODE_NORMAL is the only valid choise for orthogonal filters */
    if ((fb->type == ORTHOGONAL) && (hdr->tc.mode != EPS_MODE_NORMAL)) {
        return EPS_FORMAT_ERROR;
    }

    assert(chk_pos);
    /* Compute header CRC and compare it against stored one */
    hdr_crc = epsilon_crc32(buf, chk_pos - (char *) buf);
    hdr_crc = (hdr_crc ^ (hdr_crc >> 16)) & 0xffff;

    if (hdr_crc == hdr->chk) {
        hdr->chk_flag = EPS_GOOD_CRC;
    } else {
        hdr->chk_flag = EPS_BAD_CRC;
    }
    /* Compute data CRC and compare it against stored one */
    data_crc = epsilon_crc32(buf + hdr->hdr_size, hdr->data_size);

    if (data_crc == hdr->crc) {
        hdr->crc_flag = EPS_GOOD_CRC;
    } else {
        hdr->crc_flag = EPS_BAD_CRC;
    }
    return EPS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index