X-Git-Url: https://main.carlh.net/gitweb/?p=openjpeg.git;a=blobdiff_plain;f=src%2Fbin%2Fjp2%2Fconvert.c;h=fa02e31c5a458a7d1a7e41b231756bc82d20ad0e;hp=5459f7d44533e0fccc66a4be5eb7fc01cc7f731c;hb=98363e244e027c731f73ee8239d3c19451a9153b;hpb=17ea17f487a777d14bd322ac06c4e6cb9124a226 diff --git a/src/bin/jp2/convert.c b/src/bin/jp2/convert.c index 5459f7d4..fa02e31c 100644 --- a/src/bin/jp2/convert.c +++ b/src/bin/jp2/convert.c @@ -1163,6 +1163,7 @@ opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) opj_image_cmptparm_t cmptparm; /* maximum of 1 component */ opj_image_t * image = NULL; int adjustS, ushift, dshift, force8; + OPJ_UINT64 expected_file_size; char endian1, endian2, sign; char signtmp[32]; @@ -1185,7 +1186,7 @@ opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) } fseek(f, 0, SEEK_SET); - if (fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d", temp, &endian1, + if (fscanf(f, "PG%31[ \t]%c%c%31[ \t+-]%d%31[ \t]%d%31[ \t]%d", temp, &endian1, &endian2, signtmp, &prec, temp, &w, temp, &h) != 9) { fclose(f); fprintf(stderr, @@ -1213,6 +1214,29 @@ opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) return NULL; } + if (w < 1 || h < 1 || prec < 1 || prec > 31) { + fclose(f); + fprintf(stderr, "Bad pgx header, please check input file\n"); + return NULL; + } + + expected_file_size = + (OPJ_UINT64)w * (OPJ_UINT64)h * (prec > 16 ? 4 : prec > 8 ? 2 : 1); + if (expected_file_size > 10000000U) { + char ch; + long curpos = ftell(f); + if (expected_file_size > (OPJ_UINT64)INT_MAX) { + expected_file_size = (OPJ_UINT64)INT_MAX; + } + fseek(f, (long)expected_file_size - 1, SEEK_SET); + if (fread(&ch, 1, 1, f) != 1) { + fprintf(stderr, "File too short\n"); + fclose(f); + return NULL; + } + fseek(f, curpos, SEEK_SET); + } + /* initialize image component */ cmptparm.x0 = (OPJ_UINT32)parameters->image_offset_x0; @@ -1308,7 +1332,7 @@ opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) return image; } -#define CLAMP(x,a,b) x < a ? a : (x > b ? b : x) +#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) { @@ -1388,25 +1412,62 @@ int imagetopgx(opj_image_t * image, const char *outfile) nbytes = 4; } - for (i = 0; i < w * h; i++) { - /* FIXME: clamp func is being called within a loop */ - const int val = clamp(image->comps[compno].data[i], - (int)comp->prec, (int)comp->sgnd); - - for (j = nbytes - 1; j >= 0; j--) { - int v = (int)(val >> (j * 8)); - unsigned char byte = (unsigned char)v; - res = fwrite(&byte, 1, 1, fdest); - - if (res < 1) { - fprintf(stderr, "failed to write 1 byte for %s\n", name); + if (nbytes == 1) { + unsigned char* line_buffer = malloc((size_t)w); + if (line_buffer == NULL) { + fprintf(stderr, "Out of memory"); + if (total > 256) { + free(name); + } + goto fin; + } + for (j = 0; j < h; j++) { + if (comp->prec == 8 && comp->sgnd == 0) { + for (i = 0; i < w; i++) { + line_buffer[i] = (unsigned char)CLAMP(image->comps[compno].data[j * w + i], 0, + 255); + } + } else { + for (i = 0; i < w; i++) { + line_buffer[i] = (unsigned char) + clamp(image->comps[compno].data[j * w + i], + (int)comp->prec, (int)comp->sgnd); + } + } + res = fwrite(line_buffer, 1, (size_t)w, fdest); + if (res != (size_t)w) { + fprintf(stderr, "failed to write %d bytes for %s\n", w, name); if (total > 256) { free(name); } + free(line_buffer); goto fin; } } + free(line_buffer); + } else { + + for (i = 0; i < w * h; i++) { + /* FIXME: clamp func is being called within a loop */ + const int val = clamp(image->comps[compno].data[i], + (int)comp->prec, (int)comp->sgnd); + + for (j = nbytes - 1; j >= 0; j--) { + int v = (int)(val >> (j * 8)); + unsigned char byte = (unsigned char)v; + res = fwrite(&byte, 1, 1, fdest); + + if (res < 1) { + fprintf(stderr, "failed to write 1 byte for %s\n", name); + if (total > 256) { + free(name); + } + goto fin; + } + } + } } + if (total > 256) { free(name); } @@ -1751,6 +1812,13 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) return NULL; } + if (header_info.width == 0 + || header_info.height == 0 + || (header_info.format == 7 && header_info.depth == 0)) { + fclose(fp); + return NULL; + } + /* This limitation could be removed by making sure to use size_t below */ if (header_info.height != 0 && header_info.width > INT_MAX / header_info.height) { @@ -1836,8 +1904,10 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) for (compno = 0; compno < numcomps; compno++) { index = 0; if (fscanf(fp, "%u", &index) != 1) { - fprintf(stderr, - "\nWARNING: fscanf return a number of element different from the expected.\n"); + fprintf(stderr, "Missing data. Quitting.\n"); + opj_image_destroy(image); + fclose(fp); + return NULL; } image->comps[compno].data[i] = (OPJ_INT32)(index * 255) / header_info.maxval; @@ -1855,8 +1925,7 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) for (i = 0; i < w * h; i++) { for (compno = 0; compno < numcomps; compno++) { if (!fread(&c0, 1, 1, fp)) { - fprintf(stderr, - "\nError: fread return a number of element different from the expected.\n"); + fprintf(stderr, "Missing data. Quitting.\n"); opj_image_destroy(image); fclose(fp); return NULL; @@ -1865,8 +1934,10 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) image->comps[compno].data[i] = c0; } else { if (!fread(&c1, 1, 1, fp)) { - fprintf(stderr, - "\nError: fread return a number of element different from the expected.\n"); + fprintf(stderr, "Missing data. Quitting.\n"); + opj_image_destroy(image); + fclose(fp); + return NULL; } /* netpbm: */ image->comps[compno].data[i] = ((c0 << 8) | c1); @@ -1878,15 +1949,17 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) unsigned int index; if (fscanf(fp, "%u", &index) != 1) { - fprintf(stderr, - "\nWARNING: fscanf return a number of element different from the expected.\n"); + fprintf(stderr, "Missing data. Quitting.\n"); + opj_image_destroy(image); + fclose(fp); + return NULL; } image->comps[0].data[i] = (index ? 0 : 255); } } else if (format == 4) { int x, y, bit; - unsigned char uc; + int uc; i = 0; for (y = 0; y < h; ++y) { @@ -1896,9 +1969,15 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) for (x = 0; x < w; ++x) { if (bit == -1) { bit = 7; - uc = (unsigned char)getc(fp); + uc = getc(fp); + if (uc == EOF) { + fprintf(stderr, "Missing data. Quitting.\n"); + opj_image_destroy(image); + fclose(fp); + return NULL; + } } - image->comps[0].data[i] = (((uc >> bit) & 1) ? 0 : 255); + image->comps[0].data[i] = ((((unsigned char)uc >> bit) & 1) ? 0 : 255); --bit; ++i; } @@ -1908,8 +1987,10 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) for (i = 0; i < w * h; ++i) { if (!fread(&uc, 1, 1, fp)) { - fprintf(stderr, - "\nError: fread return a number of element different from the expected.\n"); + fprintf(stderr, "Missing data. Quitting.\n"); + opj_image_destroy(image); + fclose(fp); + return NULL; } image->comps[0].data[i] = (uc & 1) ? 0 : 255; }