[trunk] Partially rework r2506, original patch from issue 171 was totally bogus (untested?) and did break most of the test (eg. p1_04 family)

convert.c duplicate a lot of code, this patch only adresses the PGX codec section of the code.
Update issue 171
Update issue 264
This commit is contained in:
Mathieu Malaterre 2014-02-28 17:29:28 +00:00
parent 978de6fb97
commit ec593a2549
1 changed files with 82 additions and 71 deletions

View File

@ -1416,90 +1416,101 @@ opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) {
return image; return image;
} }
#define CLAMP(x,a,b) x < a ? a : (x > b ? b : x)
static inline int clamp( const int value, const int prec, const int sgnd )
{
if( sgnd )
{
if (prec <= 8) return CLAMP(value,-128,127);
else if (prec <= 16) return CLAMP(value,-32768,32767);
else return CLAMP(value,-2147483648,2147483647);
}
else
{
if (prec <= 8) return CLAMP(value,0,255);
else if (prec <= 16) return CLAMP(value,0,65535);
else return CLAMP(value,0,4294967295);
}
}
int imagetopgx(opj_image_t * image, const char *outfile) int imagetopgx(opj_image_t * image, const char *outfile)
{ {
int w, h; int w, h;
int i, j, compno, fails; int i, j, compno, fails = 1;
FILE *fdest = NULL; FILE *fdest = NULL;
for (compno = 0; compno < image->numcomps; compno++) for (compno = 0; compno < image->numcomps; compno++)
{ {
opj_image_comp_t *comp = &image->comps[compno]; opj_image_comp_t *comp = &image->comps[compno];
char bname[256]; /* buffer for name */ char bname[256]; /* buffer for name */
char *name = bname; /* pointer */ char *name = bname; /* pointer */
int nbytes = 0; int nbytes = 0;
size_t res; size_t res;
const size_t olen = strlen(outfile); const size_t olen = strlen(outfile);
const size_t dotpos = olen - 4; const size_t dotpos = olen - 4;
const size_t total = dotpos + 1 + 1 + 4; /* '-' + '[1-3]' + '.pgx' */ const size_t total = dotpos + 1 + 1 + 4; /* '-' + '[1-3]' + '.pgx' */
if( outfile[dotpos] != '.' ) if( outfile[dotpos] != '.' )
{ {
/* `pgx` was recognized but there is no dot at expected position */ /* `pgx` was recognized but there is no dot at expected position */
fprintf(stderr, "ERROR -> Impossible happen." ); fprintf(stderr, "ERROR -> Impossible happen." );
return 1; goto fin;
} }
if( total > 256 ) if( total > 256 )
{ {
name = (char*)malloc(total+1); name = (char*)malloc(total+1);
} }
strncpy(name, outfile, dotpos); strncpy(name, outfile, dotpos);
/*if (image->numcomps > 1) {*/ sprintf(name+dotpos, "_%d.pgx", compno);
sprintf(name+dotpos, "_%d.pgx", compno); fdest = fopen(name, "wb");
/*} else { /* dont need name anymore */
strcpy(name+dotpos, ".pgx"); if( total > 256 ) free(name);
}*/ if (!fdest)
fdest = fopen(name, "wb"); {
if (!fdest) fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);
{ goto fin;
fprintf(stderr, "ERROR -> failed to open %s for writing\n", name); }
return 1;
}
/* dont need name anymore */
if( total > 256 )
free(name);
fails = 1;
w = image->comps[compno].w;
h = image->comps[compno].h;
fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', w = image->comps[compno].w;
comp->prec, w, h); h = image->comps[compno].h;
if (comp->prec <= 8) fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', comp->prec,
nbytes = 1; w, h);
else
if (comp->prec <= 16)
nbytes = 2;
else
nbytes = 4;
for (i = 0; i < w * h; i++) if (comp->prec <= 8)
{ nbytes = 1;
int v, val = image->comps[compno].data[i]; else if (comp->prec <= 16)
unsigned char byte; nbytes = 2;
else
nbytes = 4;
for (j = nbytes - 1; j >= 0; j--) for (i = 0; i < w * h; i++)
{ {
v = (int)(val >> (j * 8)); /* FIXME: clamp func is being called within a loop */
if(v > 255) v = 255; else if(v < 0) v = 0; const int val = clamp(image->comps[compno].data[i],
byte = (unsigned char)v; comp->prec, comp->sgnd);
res = fwrite(&byte, 1, 1, fdest);
if( res < 1 ) for (j = nbytes - 1; j >= 0; j--)
{ {
fprintf(stderr, "failed to write 1 byte for %s\n", name); int v = (int)(val >> (j * 8));
goto fin; unsigned char byte = (unsigned char)v;
} res = fwrite(&byte, 1, 1, fdest);
}
} if( res < 1 )
fclose(fdest); fdest = NULL; {
} fprintf(stderr, "failed to write 1 byte for %s\n", name);
fails = 0; goto fin;
}
}
}
fclose(fdest); fdest = NULL;
}
fails = 0;
fin: fin:
if(fdest) fclose(fdest); if(fdest) fclose(fdest);
return fails; return fails;
} }
/* -->> -->> -->> -->> /* -->> -->> -->> -->>