📄 pgxtoj2k.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 <j2k.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "getopt.h"
unsigned char readuchar(FILE *f) {
unsigned char c1;
fread(&c1, 1, 1, f);
return c1;
}
unsigned short readushort(FILE *f, int bigendian) {
unsigned char c1, c2;
fread(&c1, 1, 1, f);
fread(&c2, 1, 1, f);
if (bigendian) return (c1<<8)+c2;
else return (c2<<8)+c1;
}
unsigned int readuint(FILE *f, int bigendian) {
unsigned char c1, c2, c3, c4;
fread(&c1, 1, 1, f);
fread(&c2, 1, 1, f);
fread(&c3, 1, 1, f);
fread(&c4, 1, 1, f);
if (bigendian) return (c1<<24)+(c2<<16)+(c3<<8)+c4;
else return (c4<<24)+(c3<<16)+(c2<<8)+c1;
}
int pgxtoimage(char *filename, j2k_image_t *img) {
FILE *f;
int w, h, prec;
int i, compno;
char str[256], endian[16];
int bigendian;
j2k_comp_t *comp;
for (compno=0;; compno++) {
sprintf(str, "%s-%d.pgx", filename, compno);
printf("filename: %s\n", str);
f=fopen(str, "rb");
if (!f) break;
printf("open ok\n");
fclose(f);
}
img->numcomps=compno;
if (!img->numcomps)
return 0;
img->comps=(j2k_comp_t*)malloc(img->numcomps*sizeof(j2k_comp_t));
for (compno=0; compno<img->numcomps; compno++) {
comp=&img->comps[compno];
sprintf(str, "%s-%d.pgx", filename, compno);
f=fopen(str, "rb");
if (fscanf(f, "PG %s %d %d %d", endian, &prec, &w, &h)==4) {
fgetc(f);
if (!strcmp(endian, "ML")) bigendian=1;
else bigendian=0;
if (compno==0) {
img->x0=0; img->y0=0; img->x1=w; img->y1=h;
} else {
if (w!=img->x1 || h!=img->y1) return 0;
}
comp->data=(int*)malloc(w*h*sizeof(int));
if (prec>0) {
comp->prec=prec;
comp->sgnd=0;
} else {
comp->prec=-prec;
comp->sgnd=1;
}
comp->dx=1;
comp->dy=1;
for (i=0; i<w*h; i++) {
int v;
if (comp->prec<=8) {
if (!comp->sgnd) {
v=readuchar(f);
} else {
v=(char)readuchar(f);
}
} else if (comp->prec<=16) {
if (!comp->sgnd) {
v=readushort(f, bigendian);
} else {
v=(short)readushort(f, bigendian);
}
} else {
if (!comp->sgnd) {
v=readuint(f, bigendian);
} else {
v=(int)readuint(f, bigendian);
}
}
comp->data[i]=v;
}
} else {
return 0;
}
fclose(f);
}
return 1;
}
double dwt_norms_97[4][10]={
{1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9},
{2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
{2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
{2.080, 3.865, 8.307, 17.18, 34.71, 69.59, 139.3, 278.6, 557.2}
};
int floorlog2(int a) {
int l;
for (l=0; a>1; l++) {
a>>=1;
}
return l;
}
void encode_stepsize(int stepsize, int numbps, int *expn, int *mant) {
int p, n;
p=floorlog2(stepsize)-13;
n=11-floorlog2(stepsize);
*mant=(n<0?stepsize>>-n:stepsize<<n)&0x7ff;
*expn=numbps-p;
}
void calc_explicit_stepsizes(j2k_tccp_t *tccp, int prec) {
int numbands, bandno;
numbands=3*tccp->numresolutions-2;
for (bandno=0; bandno<numbands; bandno++) {
double stepsize;
int resno, level, orient, gain;
resno=bandno==0?0:(bandno-1)/3+1;
orient=bandno==0?0:(bandno-1)%3+1;
level=tccp->numresolutions-1-resno;
gain=tccp->qmfbid==0?0:(orient==0?0:(orient==1||orient==2?1:2));
if (tccp->qntsty==J2K_CCP_QNTSTY_NOQNT) {
stepsize=1.0;
} else {
double norm=dwt_norms_97[orient][level];
stepsize=(1<<(gain+1))/norm;
}
encode_stepsize((int)floor(stepsize*8192.0), prec+gain, &tccp->stepsizes[bandno].expn, &tccp->stepsizes[bandno].mant);
}
}
int main(int argc, char **argv)
{
FILE *f;
unsigned char *dest; //++pac
int len;
j2k_image_t img;
j2k_cp_t cp;
j2k_tcp_t *tcp;
j2k_tccp_t *tccp;
int i;
char *infile=0, *outfile=0;
char *s;
int ir=0;
cp.tx0=0; cp.ty0=0;
cp.tw=1; cp.th=1;
cp.tcps=(j2k_tcp_t*)malloc(sizeof(j2k_tcp_t));
tcp=&cp.tcps[0];
tcp->numlayers=0;
while (1) {
int c=getopt(argc, argv, "i:o:r:I");
if (c==-1) break;
switch (c) {
case 'i':
infile=optarg;
break;
case 'o':
outfile=optarg;
break;
case 'r':
s=optarg;
while (sscanf(s, "%d", &tcp->rates[tcp->numlayers])==1) {
tcp->numlayers++;
while (*s && *s!=',') {s++;}
if (!*s) break;
s++;
}
break;
case 'I':
ir=1;
break;
default:
return 1;
}
}
if (!infile || !outfile || tcp->numlayers==0) {
fprintf(stderr, "usage: pgxtoj2k -i pgx-name -o j2k-file -r rates\n");
return 1;
}
if (!pgxtoimage(infile, &img)) {
fprintf(stderr, "failed to open pgx file\n");
return 1;
}
cp.tdx=img.x1-img.x0; cp.tdy=img.y1-img.y0;
tcp->csty=0;
tcp->prg=0;
tcp->mct=img.numcomps==3?1:0;
tcp->tccps=(j2k_tccp_t*)malloc(img.numcomps*sizeof(j2k_tccp_t));
for (i=0; i<img.numcomps; i++) {
tccp=&tcp->tccps[i];
tccp->csty=0;
tccp->numresolutions=6;
tccp->cblkw=6;
tccp->cblkh=6;
tccp->cblksty=0;
tccp->qmfbid=ir?0:1;
tccp->qntsty=ir?J2K_CCP_QNTSTY_SEQNT:J2K_CCP_QNTSTY_NOQNT;
tccp->numgbits=2;
tccp->roishift=0;
calc_explicit_stepsizes(tccp, img.comps[i].prec);
}
dest=(unsigned char*)malloc(tcp->rates[tcp->numlayers-1]+2); //++pac
len=j2k_encode(&img, &cp, dest, tcp->rates[tcp->numlayers-1]+2);
if (len==0) {
fprintf(stderr, "failed to encode image\n");
return 1;
}
f=fopen(outfile, "wb");
if (!f) {
fprintf(stderr, "failed to open %s for writing\n", outfile);
return 1;
}
fwrite(dest, 1, len, f);
fclose(f);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -