⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t2.c

📁 关于JPEG2000压缩标准的模板程序的内容,是我们导师给的,据说是国外的版本.
💻 C
字号:
/*
 * Copyright (c) 2001-2002, David Janssens
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "t2.h"
#include "tcd.h"
#include "bio.h"
#include "j2k.h"
#include "pi.h"
#include "tgt.h"
#include "int.h"
#include <stdio.h>
#include <setjmp.h>

extern jmp_buf j2k_error;

void t2_putcommacode(int n)
{
    while (--n>=0) {
        bio_write(1, 1);
    }
    bio_write(0, 1);
}

int t2_getcommacode() {
    int n;
    for (n=0; bio_read(1); n++) {}
    return n;
}

void t2_putnumpasses(int n)
{
    if (n==1) {
        bio_write(0, 1);
    } else if (n==2) {
        bio_write(2, 2);
    } else if (n<=5) {
        bio_write(0xc|(n-3), 4);
    } else if (n<=36) {
        bio_write(0x1e0|(n-6), 9);
    } else if (n<=164) {
        bio_write(0xff80|(n-37), 16);
    }
}

int t2_getnumpasses()
{
    int n;
    if (!bio_read(1)) return 1;
    if (!bio_read(1)) return 2;
    if ((n=bio_read(2))!=3) return 3+n;
    if ((n=bio_read(5))!=31) return 6+n;
    return 37+bio_read(7);
}

int t2_encode_packet(tcd_tile_t *tile, j2k_tcp_t *tcp, int compno, int resno, int precno, int layno, unsigned char *dest, int len) {
    int bandno, cblkno;
    tcd_tilecomp_t *tilec=&tile->comps[compno];
    tcd_resolution_t *res=&tilec->resolutions[resno];
    unsigned char *c=dest;
    if (!layno) {
        for (bandno=0; bandno<res->numbands; bandno++) {
            tcd_band_t *band=&res->bands[bandno];
            tcd_precinct_t *prc=&band->precincts[precno];
            tgt_reset(prc->incltree);
            tgt_reset(prc->imsbtree);
            for (cblkno=0; cblkno<prc->cw*prc->ch; cblkno++) {
                tcd_cblk_t *cblk=&prc->cblks[cblkno];
                cblk->numpasses=0;
                tgt_setvalue(prc->imsbtree, cblkno, band->numbps-cblk->numbps);
            }
        }
    }
    bio_init_enc(c, len);
    bio_write(1, 1);
    for (bandno=0; bandno<res->numbands; bandno++) {
        tcd_band_t *band=&res->bands[bandno];
        tcd_precinct_t *prc=&band->precincts[precno];
        for (cblkno=0; cblkno<prc->cw*prc->ch; cblkno++) {
            tcd_cblk_t *cblk=&prc->cblks[cblkno];
            tcd_layer_t *layer=&cblk->layers[layno];
            if (!cblk->numpasses && layer->numpasses) {
                tgt_setvalue(prc->incltree, cblkno, layno);
            }
        }
        for (cblkno=0; cblkno<prc->cw*prc->ch; cblkno++) {
            tcd_cblk_t *cblk=&prc->cblks[cblkno];
            tcd_layer_t *layer=&cblk->layers[layno];
            int increment;
            if (!cblk->numpasses) {
                tgt_encode(prc->incltree, cblkno, layno+1);
            } else {
                bio_write(layer->numpasses!=0, 1);
            }
            if (!layer->numpasses) {
                continue;
            }
            if (!cblk->numpasses) {
                cblk->numlenbits=3;
                tgt_encode(prc->imsbtree, cblkno, 999);
            }
            t2_putnumpasses(layer->numpasses);
            increment=int_max(0, int_floorlog2(layer->len)+1-(cblk->numlenbits+int_floorlog2(layer->numpasses)));
            t2_putcommacode(increment);
            cblk->numlenbits+=increment;
            bio_write(layer->len, cblk->numlenbits+int_floorlog2(layer->numpasses));
        }
    }
    bio_flush();
    c+=bio_numbytes();
    for (bandno=0; bandno<res->numbands; bandno++) {
        tcd_band_t *band=&res->bands[bandno];
        tcd_precinct_t *prc=&band->precincts[precno];
        for (cblkno=0; cblkno<prc->cw*prc->ch; cblkno++) {
            tcd_cblk_t *cblk=&prc->cblks[cblkno];
            tcd_layer_t *layer=&cblk->layers[layno];
            if (!layer->numpasses) continue;
            if (c+layer->len>dest+len) {
                longjmp(j2k_error, 1);
            }
            memcpy(c, layer->data, layer->len);
            cblk->numpasses+=layer->numpasses;
            c+=layer->len;
        }
    }
    return c-dest;
}

void t2_init_seg(tcd_seg_t *seg, int cblksty) {
    seg->numpasses=0;
    seg->len=0;
    seg->maxpasses=cblksty&J2K_CCP_CBLKSTY_TERMALL?1:100;
}

int t2_decode_packet(unsigned char *src, int len, tcd_tile_t *tile, j2k_tcp_t *tcp, int compno, int resno, int precno, int layno) {
    int bandno, cblkno;
    tcd_tilecomp_t *tilec=&tile->comps[compno];
    tcd_resolution_t *res=&tilec->resolutions[resno];
    unsigned char *c=src;
    int present;
    if (layno==0) {
        for (bandno=0; bandno<res->numbands; bandno++) {
            tcd_band_t *band=&res->bands[bandno];
            tcd_precinct_t *prc=&band->precincts[precno];
            tgt_reset(prc->incltree);
            tgt_reset(prc->imsbtree);
            for (cblkno=0; cblkno<prc->cw*prc->ch; cblkno++) {
                tcd_cblk_t *cblk=&prc->cblks[cblkno];
                cblk->numsegs=0;
            }
        }
    }
    if (tcp->csty&J2K_CP_CSTY_SOP) {
        c+=6;
    }
    bio_init_dec(c, src+len-c);
    present=bio_read(1);
    if (!present) {
        bio_inalign();
        c+=bio_numbytes();
        return c-src;
    }
    for (bandno=0; bandno<res->numbands; bandno++) {
        tcd_band_t *band=&res->bands[bandno];
        tcd_precinct_t *prc=&band->precincts[precno];
        for (cblkno=0; cblkno<prc->cw*prc->ch; cblkno++) {
            int included, increment, n;
            tcd_cblk_t *cblk=&prc->cblks[cblkno];
            tcd_seg_t *seg;
            if (!cblk->numsegs) {
                included=tgt_decode(prc->incltree, cblkno, layno+1);
            } else {
                included=bio_read(1);
            }
            if (!included) {
                cblk->numnewpasses=0;
                continue;
            }
            if (!cblk->numsegs) {
                int i, numimsbs;
                for (i=0; !tgt_decode(prc->imsbtree, cblkno, i); i++) {}
                numimsbs=i-1;
                cblk->numbps=band->numbps-numimsbs;
                cblk->numlenbits=3;
            }
            cblk->numnewpasses=t2_getnumpasses();
            increment=t2_getcommacode();
            cblk->numlenbits+=increment;
            if (!cblk->numsegs) {
                seg=&cblk->segs[0];
                t2_init_seg(seg, tcp->tccps[compno].cblksty);
            } else {
                seg=&cblk->segs[cblk->numsegs-1];
                if (seg->numpasses==seg->maxpasses) {
                    t2_init_seg(++seg, tcp->tccps[compno].cblksty);
                }
            }
            n=cblk->numnewpasses;
            do {
                seg->numnewpasses=int_min(seg->maxpasses-seg->numpasses, n);
                seg->newlen=bio_read(cblk->numlenbits+int_floorlog2(seg->numnewpasses));
                n-=seg->numnewpasses;
                if (n>0) {
                    t2_init_seg(++seg, tcp->tccps[compno].cblksty);
                }
            } while (n>0);
        }
    }
    bio_inalign();
    c+=bio_numbytes();
    if (tcp->csty&J2K_CP_CSTY_EPH) {
        c+=2;
    }
    for (bandno=0; bandno<res->numbands; bandno++) {
        tcd_band_t *band=&res->bands[bandno];
        tcd_precinct_t *prc=&band->precincts[precno];
        for (cblkno=0; cblkno<prc->cw*prc->ch; cblkno++) {
            tcd_cblk_t *cblk=&prc->cblks[cblkno];
            tcd_seg_t *seg;
            if (!cblk->numnewpasses) continue;
            if (!cblk->numsegs) {
                seg=&cblk->segs[cblk->numsegs++];
                cblk->len=0;
            } else {
                seg=&cblk->segs[cblk->numsegs-1];
                if (seg->numpasses==seg->maxpasses) {
                    seg++;
                    cblk->numsegs++;
                }
            }
            do {
                if (c+seg->newlen>src+len) longjmp(j2k_error, 1);
                memcpy(cblk->data+cblk->len, c, seg->newlen);
                if (seg->numpasses==0) {
                    seg->data=cblk->data+cblk->len;
                }
                c+=seg->newlen;
                cblk->len+=seg->newlen;
                seg->len+=seg->newlen;
                seg->numpasses+=seg->numnewpasses;
                cblk->numnewpasses-=seg->numnewpasses;
                if (cblk->numnewpasses>0) {
                    seg++;
                    cblk->numsegs++;
                }
            } while (cblk->numnewpasses>0);
        }
    }
    return c-src;
}

int t2_encode_packets(j2k_image_t *img, j2k_cp_t *cp, int tileno, tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len) {
    unsigned char *c=dest;
    pi_iterator_t *pi;
    pi=pi_create(img, cp, tileno);
    while (pi_next(pi)) {
        if (pi->layno<maxlayers) {
            //fprintf(stderr, "compno=%d, resno=%d, precno=%d, layno=%d\n", pi->compno, pi->resno, pi->precno, pi->layno);
            c+=t2_encode_packet(tile, &cp->tcps[tileno], pi->compno, pi->resno, pi->precno, pi->layno, c, dest+len-c);
        }
    }
    return c-dest;
}

int t2_decode_packets(unsigned char *src, int len, j2k_image_t *img, j2k_cp_t *cp, int tileno, tcd_tile_t *tile) {
    unsigned char *c=src;
    pi_iterator_t *pi;
    pi=pi_create(img, cp, tileno);
    while (pi_next(pi)) {
        //fprintf(stderr, "compno=%d, resno=%d, precno=%d, layno=%d\n", pi->compno, pi->resno, pi->precno, pi->layno);
        c+=t2_decode_packet(c, src+len-c, tile, &cp->tcps[tileno], pi->compno, pi->resno, pi->precno, pi->layno);
    }
    return c-src;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -