Commit a0777eb2 authored by Mathieu Malaterre's avatar Mathieu Malaterre

Import Upstream version 2.3.0

parent 7bd7546e
# Changelog
## [v2.2.0]("https://github.com/uclouvain/openjpeg/releases/v2.2.0" ) (2017-08-10)
## [v2.3.0](https://github.com/uclouvain/openjpeg/releases/v2.3.0) (2017-10-04)
[Full Changelog](https://github.com/uclouvain/openjpeg/compare/v2.2.0...v2.3.0)
**Implemented enhancements:**
- Sub-tile decoding: only decode precincts and codeblocks that intersect the window specified in opj_set_decode_area() [\#990](https://github.com/uclouvain/openjpeg/pull/990) ([rouault](https://github.com/rouault))
- Sub-tile decoding: only apply IDWT on areas that participate to the window of interest [\#1001](https://github.com/uclouvain/openjpeg/pull/1001) ([rouault](https://github.com/rouault))
- Sub-tile decoding: memory use reduction and perf improvements [\#1010](https://github.com/uclouvain/openjpeg/pull/1010) ([rouault](https://github.com/rouault))
- Add capability to decode only a subset of all components of an image. [\#1022](https://github.com/uclouvain/openjpeg/pull/1022) ([rouault](https://github.com/rouault))
**Fixed bugs:**
- Setting x offset of decode region to -1 causes opj\_decompress to go into infinite loop [\#736](https://github.com/uclouvain/openjpeg/issues/736)
- Problem decoding multiple tiles with get\_decoded\_tile when cmap/pclr/cdef boxes are present in jp2 file [\#484](https://github.com/uclouvain/openjpeg/issues/484)
- set reduce\_factor\_may\_fail [\#474](https://github.com/uclouvain/openjpeg/issues/474)
- opj\_compress.exe, command line parser, infinite loop [\#469](https://github.com/uclouvain/openjpeg/issues/469)
- Various memory access issues found via fuzzing [\#448](https://github.com/uclouvain/openjpeg/issues/448)
- Multiple warnings when building OpenJPEG \(trunk\) [\#442](https://github.com/uclouvain/openjpeg/issues/442)
- Bulk fuzz-testing report [\#427](https://github.com/uclouvain/openjpeg/issues/427)
- remove all printf from openjpeg / use proper function pointer for logging [\#371](https://github.com/uclouvain/openjpeg/issues/371)
- minor changes, clean-up [\#349](https://github.com/uclouvain/openjpeg/issues/349)
- image-\>numcomps \> 4 [\#333](https://github.com/uclouvain/openjpeg/issues/333)
- Improve support for region of interest [\#39](https://github.com/uclouvain/openjpeg/issues/39)
- Public function to tell kernel type used \(5x3 vs 9x7\) [\#3](https://github.com/uclouvain/openjpeg/issues/3)
- elf binary in source package ? [\#1026](https://github.com/uclouvain/openjpeg/issues/1026)
- opj\_cio\_open [\#1025](https://github.com/uclouvain/openjpeg/issues/1025)
- Building with Visual Studio 2015 [\#1023](https://github.com/uclouvain/openjpeg/issues/1023)
- tcd.cpp\>:1617:33: error: assigning to 'OPJ\_INT32 \*' \(aka 'int \*'\) from incompatible type 'void \*' [\#1021](https://github.com/uclouvain/openjpeg/issues/1021)
- j2k.cpp \> comparison of address of 'p\_j2k-\>m\_cp.tcps\[0\].m\_data' not equal to a null pointer is always true [\#1020](https://github.com/uclouvain/openjpeg/issues/1020)
- Openjpeg 2.2.0 always build shared library even though -DBUILD\_SHARED\_LIBS:bool=off [\#1019](https://github.com/uclouvain/openjpeg/issues/1019)
- missing fclose [\#1018](https://github.com/uclouvain/openjpeg/issues/1018)
- Use opj\_image\_data\_free instead of opj\_free for image-\>comps\[\].data [\#1014](https://github.com/uclouvain/openjpeg/issues/1014)
- malloc poison on some compilers - cross compiling [\#1013](https://github.com/uclouvain/openjpeg/issues/1013)
- Add OPJ\_VERSION\_MAJOR, OPJ\_VERSION\_MINOR, OPJ\_VERSION\_MICRO macros in openjpeg.h [\#1011](https://github.com/uclouvain/openjpeg/issues/1011)
- Encode: do not perform rate control for single-tile lossless [\#1009](https://github.com/uclouvain/openjpeg/issues/1009)
- opj\_set\_decoded\_resolution\_factor\(\): bad interaction with opj\_set\_decode\_area\(\) and/or opj\_decode\(\) [\#1006](https://github.com/uclouvain/openjpeg/issues/1006)
- memory allocation failure with .pgx file [\#999](https://github.com/uclouvain/openjpeg/issues/999)
- Unable to fuzz with raw image as input [\#998](https://github.com/uclouvain/openjpeg/issues/998)
- stack-based buffer overflow write in pgxtoimage \(/convert.c\) [\#997](https://github.com/uclouvain/openjpeg/issues/997)
- freeze with a crafted bmp [\#996](https://github.com/uclouvain/openjpeg/issues/996)
- invalid memory write in tgatoimage \(convert.c\) [\#995](https://github.com/uclouvain/openjpeg/issues/995)
- static build on Windows fails [\#994](https://github.com/uclouvain/openjpeg/issues/994)
- another heap-based buffer overflow in opj\_t2\_encode\_packet \(t2.c\) [\#993](https://github.com/uclouvain/openjpeg/issues/993)
- heap-based buffer overflow in opj\_t2\_encode\_packet \(t2.c\) [\#992](https://github.com/uclouvain/openjpeg/issues/992)
- heap-based buffer overflow in opj\_write\_bytes\_LE \(cio.c\) \(unfixed \#985\) [\#991](https://github.com/uclouvain/openjpeg/issues/991)
- heap overflow in opj\_compress [\#988](https://github.com/uclouvain/openjpeg/issues/988)
- heap overflow in opj\_decompress [\#987](https://github.com/uclouvain/openjpeg/issues/987)
- heap-based buffer overflow in opj\_bio\_byteout \(bio.c\) [\#986](https://github.com/uclouvain/openjpeg/issues/986)
- heap-based buffer overflow in opj\_write\_bytes\_LE \(cio.c\) [\#985](https://github.com/uclouvain/openjpeg/issues/985)
- memory allocation failure in opj\_aligned\_alloc\_n \(opj\_malloc.c\) [\#983](https://github.com/uclouvain/openjpeg/issues/983)
- heap-base buffer overflow in opj\_mqc\_flush \(mqc.c\) [\#982](https://github.com/uclouvain/openjpeg/issues/982)
- Decode fails for JP2s with ICC profile [\#981](https://github.com/uclouvain/openjpeg/issues/981)
- Unit tests failing on Ubuntu 17.04 [\#916](https://github.com/uclouvain/openjpeg/issues/916)
- Encoder crashes on small images [\#901](https://github.com/uclouvain/openjpeg/issues/901)
- openjpeg-1.5.3 fails to compile [\#830](https://github.com/uclouvain/openjpeg/issues/830)
- opj\_compress crops image \(win\) or creates a jp2 which cannot be decompressed \(lin\) [\#716](https://github.com/uclouvain/openjpeg/issues/716)
- -d flag is silently ignored when decoding a single tile [\#693](https://github.com/uclouvain/openjpeg/issues/693)
- transition away from dev-utils [\#628](https://github.com/uclouvain/openjpeg/issues/628)
- update instructions to build with Visual Studio and 64-Bit Visual C++ Toolset. [\#1028](https://github.com/uclouvain/openjpeg/pull/1028) ([quangnh89](https://github.com/quangnh89))
- Add missing newline at end of file [\#1024](https://github.com/uclouvain/openjpeg/pull/1024) ([stweil](https://github.com/stweil))
- merge master into coverity\_scan to update coverity results [\#1008](https://github.com/uclouvain/openjpeg/pull/1008) ([detonin](https://github.com/detonin))
- Use more const qualifiers [\#984](https://github.com/uclouvain/openjpeg/pull/984) ([stweil](https://github.com/stweil))
- Changes in converttif.c for PPC64 [\#980](https://github.com/uclouvain/openjpeg/pull/980) ([szukw000](https://github.com/szukw000))
## [v2.2.0](https://github.com/uclouvain/openjpeg/releases/v2.2.0) (2017-08-10)
[Full Changelog](https://github.com/uclouvain/openjpeg/compare/v2.1.2...v2.2.0)
**Implemented enhancements:**
......
......@@ -32,7 +32,7 @@ include_regular_expression("^.*$")
#-----------------------------------------------------------------------------
# OPENJPEG version number, useful for packaging and doxygen doc:
set(OPENJPEG_VERSION_MAJOR 2)
set(OPENJPEG_VERSION_MINOR 2)
set(OPENJPEG_VERSION_MINOR 3)
set(OPENJPEG_VERSION_BUILD 0)
set(OPENJPEG_VERSION
"${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}.${OPENJPEG_VERSION_BUILD}")
......@@ -55,6 +55,7 @@ set(PACKAGE_VERSION
# 2.1.1 | 7
# 2.1.2 | 7
# 2.2.0 | 7
# 2.3.0 | 7
# above is the recommendation by the OPJ team. If you really need to override this default,
# you can specify your own OPENJPEG_SOVERSION at cmake configuration time:
# cmake -DOPENJPEG_SOVERSION:STRING=42 /path/to/openjpeg
......@@ -173,6 +174,7 @@ configure_file(
#-----------------------------------------------------------------------------
# OpenJPEG build configuration options.
option(BUILD_SHARED_LIBS "Build OpenJPEG shared library and link executables against it." ON)
option(BUILD_STATIC_LIBS "Build OpenJPEG static library." ON)
set (EXECUTABLE_OUTPUT_PATH ${OPENJPEG_BINARY_DIR}/bin CACHE PATH "Single output directory for building all executables.")
set (LIBRARY_OUTPUT_PATH ${OPENJPEG_BINARY_DIR}/bin CACHE PATH "Single output directory for building all libraries.")
mark_as_advanced(LIBRARY_OUTPUT_PATH EXECUTABLE_OUTPUT_PATH)
......@@ -253,7 +255,7 @@ if(BUILD_JPIP_SERVER)
endif()
add_subdirectory(src/lib)
option(BUILD_LUTS_GENERATOR "Build utility to generate t1_luts.h" OFF)
option(BUILD_BENCH_DWT "Build bench_dwt utility (development benchmark)" OFF)
option(BUILD_UNIT_TESTS "Build unit tests (bench_dwt, test_sparse_array, etc..)" OFF)
#-----------------------------------------------------------------------------
# Build Applications
......
......@@ -61,7 +61,35 @@ Note 4 : On MacOS, if it does not work, try adding the following flag to the cma
## MacOS (XCode) - WINDOWS (VisualStudio, etc)
You can use cmake to generate the project files for the IDE you are using (VC2010, XCode, etc).
Type 'cmake --help' for available generators on your platform.
Type `cmake --help` for available generators on your platform.
Examples for Windows with Visual Studio C++ compiler:
If using directly the cl compiler:
```
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE:string="Release" -DBUILD_SHARED_LIBS:bool=on -DCMAKE_INSTALL_PREFIX:path="%USERPROFILE%" -DCMAKE_LIBRARY_PATH:path="%USERPROFILE%" -DCMAKE_INCLUDE_PATH:path="%USERPROFILE%\include" ..
```
To compile a 64-bit application, open 64-Bit Visual C\+\+ toolset on the command line and run cmake. For further information, please refer to: [How to: Enable a 64-Bit Visual C\+\+ Toolset on the Command Line](https://msdn.microsoft.com/en-us/library/x4d2c09s.aspx).
If you do not want directly use the cl compiler, you could use:
```
cmake -DCMAKE_BUILD_TYPE:string="Release" -DBUILD_SHARED_LIBS:bool=on -DCMAKE_INSTALL_PREFIX:path="%USERPROFILE%" -DCMAKE_LIBRARY_PATH:path="%USERPROFILE%" -DCMAKE_INCLUDE_PATH:path="%USERPROFILE%\include" ..
```
To create Visual Studio solution (.sln) and project files (.vcproj / .vcxproj):
```
cmake -G "Visual Studio 14 2015" -DCMAKE_BUILD_TYPE:string="Release" -DBUILD_SHARED_LIBS:bool=on -DCMAKE_INSTALL_PREFIX:path="%USERPROFILE%" -DCMAKE_LIBRARY_PATH:path="%USERPROFILE%" -DCMAKE_INCLUDE_PATH:path="%USERPROFILE%\include" ..
```
64-bit application:
```
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_BUILD_TYPE:string="Release" -DBUILD_SHARED_LIBS:bool=on -DCMAKE_INSTALL_PREFIX:path="%USERPROFILE%" -DCMAKE_LIBRARY_PATH:path="%USERPROFILE%" -DCMAKE_INCLUDE_PATH:path="%USERPROFILE%\include" ..
```
# Enabling CPU specific optimizations
......@@ -74,21 +102,27 @@ CPUs)
With gcc/clang, it is possible to enable those instruction sets with the following :
```
cmake -DCMAKE_C_FLAGS="-O3 -msse4.1 -DNDEBUG" ..
```
```
cmake -DCMAKE_C_FLAGS="-O3 -mavx2 -DNDEBUG" ..
```
(AVX2 implies SSE4.1)
Or if the binary is dedicated to run on the machine where it has
been compiled :
```
cmake -DCMAKE_C_FLAGS="-O3 -march=native -DNDEBUG" ..
```
# Modifying OpenJPEG
Before committing changes, run:
scripts/prepare-commit.sh
```scripts/prepare-commit.sh```
# Using OpenJPEG
......
......@@ -2,7 +2,18 @@
More details in the [Changelog](https://github.com/uclouvain/openjpeg/blob/master/CHANGELOG.md)
## OpenJPEG 2.2.0
## OpenJPEG 2.3.0 (October 2017)
No API/ABI break compared to v2.2.0 but additional symbols for subset of components decoding (hence the MINOR version bump).
* Sub-tile decoding: when setting a window of interest through the API function opj_set_decode_area(), only codeblocks that intersect this window are now decoded (i.e. MCT, IDWT, and entropy decoding are only done on the window of interest). Moreover, memory allocation now depends on the size of the window of interest (instead of the full tile size).
[\#990](https://github.com/uclouvain/openjpeg/pull/990) [\#1001](https://github.com/uclouvain/openjpeg/pull/1001) [\#1010](https://github.com/uclouvain/openjpeg/pull/1010)
* Ability to decode only a subset of components. This adds the following function `opj_set_decoded_components(opj_codec_t p_codec, OPJ_UINT32 numcomps, const OPJ_UINT32 comps_indices, OPJ_BOOL apply_color_transforms)` and equivalent `opj_decompress -c compno[,compno]*`
option.
[\#1022](https://github.com/uclouvain/openjpeg/pull/1022)
* Many bug fixes (including security fixes)
## OpenJPEG 2.2.0 (August 2017)
No API/ABI break compared to v2.1.2 but additional symbols for multithreading support (hence the MINOR version bump).
......@@ -24,18 +35,18 @@ No API/ABI break compared to v2.1.2 but additional symbols for multithreading su
* Codebase reformatting (with astyle) and scripts to automatically check that new commits comply with formatting guidelines [\#919](https://github.com/uclouvain/openjpeg/pull/919)
* Register OpenJPEG at Google OSS Fuzz initiative, so as to automatically have OpenJPEG tested against Google fuzzer [\#965](https://github.com/uclouvain/openjpeg/issues/965)
## OpenJPEG 2.1.2
## OpenJPEG 2.1.2 (September 2016)
* Bug fixes (including security fixes)
* No API/ABI break compared to v2.1.1
## OpenJPEG 2.1.1
## OpenJPEG 2.1.1 (July 2016)
* Huge amount of critical bugfixes
* Speed improvements
* No API/ABI break compared to v2.1
## OpenJPEG 2.1.0
## OpenJPEG 2.1.0 (April 2014)
### New Features
......
version: 2.2.0.{build}
version: 2.3.0.{build}
branches:
except:
- coverity_scan
......
......@@ -160,12 +160,15 @@ again:
}
if (argv[opj_optind][0] == '-') { /* long option */
char* arg = argv[opj_optind] + 1;
char* arg;
const opj_option_t* o;
o = longopts;
len = sizeof(longopts[0]);
if (param > 1) {
if (opj_optind + 1 >= argc) {
return -1;
}
arg = argv[opj_optind + 1];
opj_optind++;
} else {
......@@ -240,6 +243,7 @@ again:
'-') { /* Has read next input parameter: No arg for current parameter */
if (opj_opterr) {
fprintf(stderr, "%s: option requires an argument\n", arg);
++opj_optind;
return (BADCH);
}
}
......@@ -247,6 +251,7 @@ again:
if (!opj_optarg) { /* missing argument */
if (opj_opterr) {
fprintf(stderr, "%s: option requires an argument\n", arg);
++opj_optind;
return (BADCH);
}
}
......
......@@ -580,13 +580,10 @@ struct tga_header {
};
#endif /* INFORMATION_ONLY */
static unsigned short get_ushort(const unsigned char *data)
/* Returns a ushort from a little-endian serialized value */
static unsigned short get_tga_ushort(const unsigned char *data)
{
unsigned short val = *(const unsigned short *)data;
#ifdef OPJ_BIG_ENDIAN
val = ((val & 0xffU) << 8) | (val >> 8);
#endif
return val;
return (unsigned short)(data[0] | (data[1] << 8));
}
#define TGA_HEADER_SIZE 18
......@@ -613,17 +610,17 @@ static int tga_readheader(FILE *fp, unsigned int *bits_per_pixel,
id_len = tga[0];
/*cmap_type = tga[1];*/
image_type = tga[2];
/*cmap_index = get_ushort(&tga[3]);*/
cmap_len = get_ushort(&tga[5]);
/*cmap_index = get_tga_ushort(&tga[3]);*/
cmap_len = get_tga_ushort(&tga[5]);
cmap_entry_size = tga[7];
#if 0
x_origin = get_ushort(&tga[8]);
y_origin = get_ushort(&tga[10]);
x_origin = get_tga_ushort(&tga[8]);
y_origin = get_tga_ushort(&tga[10]);
#endif
image_w = get_ushort(&tga[12]);
image_h = get_ushort(&tga[14]);
image_w = get_tga_ushort(&tga[12]);
image_h = get_tga_ushort(&tga[14]);
pixel_depth = tga[16];
image_desc = tga[17];
......@@ -817,6 +814,25 @@ opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters)
color_space = OPJ_CLRSPC_SRGB;
}
/* If the declared file size is > 10 MB, check that the file is big */
/* enough to avoid excessive memory allocations */
if (image_height != 0 &&
image_width > 10000000U / image_height / (OPJ_UINT32)numcomps) {
char ch;
OPJ_UINT64 expected_file_size =
(OPJ_UINT64)image_width * image_height * (OPJ_UINT32)numcomps;
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) {
fclose(f);
return NULL;
}
fseek(f, curpos, SEEK_SET);
}
subsampling_dx = parameters->subsampling_dx;
subsampling_dy = parameters->subsampling_dy;
......@@ -941,7 +957,7 @@ int imagetotga(opj_image_t * image, const char *outfile)
int width, height, bpp, x, y;
OPJ_BOOL write_alpha;
unsigned int i;
int adjustR, adjustG, adjustB, fails;
int adjustR, adjustG = 0, adjustB = 0, fails;
unsigned int alpha_channel;
float r, g, b, a;
unsigned char value;
......@@ -986,8 +1002,10 @@ int imagetotga(opj_image_t * image, const char *outfile)
scale = 255.0f / (float)((1 << image->comps[0].prec) - 1);
adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
if (image->numcomps >= 3) {
adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
}
for (y = 0; y < height; y++) {
unsigned int index = (unsigned int)(y * width);
......@@ -1145,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];
......@@ -1167,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,
......@@ -1195,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;
......@@ -1290,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)
{
......@@ -1370,25 +1412,59 @@ 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");
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);
}
......
......@@ -392,6 +392,10 @@ static OPJ_BOOL bmp_read_info_header(FILE* IN, OPJ_BITMAPINFOHEADER* header)
header->biBitCount = (OPJ_UINT16)getc(IN);
header->biBitCount |= (OPJ_UINT16)((OPJ_UINT32)getc(IN) << 8);
if (header->biBitCount == 0) {
fprintf(stderr, "Error, invalid biBitCount %d\n", 0);
return OPJ_FALSE;
}
if (header->biSize >= 40U) {
header->biCompression = (OPJ_UINT32)getc(IN);
......@@ -525,10 +529,19 @@ static OPJ_BOOL bmp_read_rle8_data(FILE* IN, OPJ_UINT8* pData,
x = y = 0U;
while (y < height) {
int c = getc(IN);
if (c == EOF) {
return OPJ_FALSE;
}
if (c) {
int j;
OPJ_UINT8 c1 = (OPJ_UINT8)getc(IN);
int j, c1_int;
OPJ_UINT8 c1;
c1_int = getc(IN);
if (c1_int == EOF) {
return OPJ_FALSE;
}
c1 = (OPJ_UINT8)c1_int;
for (j = 0; (j < c) && (x < width) &&
((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
......@@ -536,6 +549,10 @@ static OPJ_BOOL bmp_read_rle8_data(FILE* IN, OPJ_UINT8* pData,
}
} else {
c = getc(IN);
if (c == EOF) {
return OPJ_FALSE;
}
if (c == 0x00) { /* EOL */
x = 0;
++y;
......@@ -544,19 +561,34 @@ static OPJ_BOOL bmp_read_rle8_data(FILE* IN, OPJ_UINT8* pData,
break;
} else if (c == 0x02) { /* MOVE by dxdy */
c = getc(IN);
if (c == EOF) {
return OPJ_FALSE;
}
x += (OPJ_UINT32)c;
c = getc(IN);
if (c == EOF) {
return OPJ_FALSE;
}
y += (OPJ_UINT32)c;
pix = pData + y * stride + x;
} else { /* 03 .. 255 */
int j;
for (j = 0; (j < c) && (x < width) &&
((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
OPJ_UINT8 c1 = (OPJ_UINT8)getc(IN);
int c1_int;
OPJ_UINT8 c1;
c1_int = getc(IN);
if (c1_int == EOF) {
return OPJ_FALSE;
}
c1 = (OPJ_UINT8)c1_int;
*pix = c1;
}
if ((OPJ_UINT32)c & 1U) { /* skip padding byte */
getc(IN);
c = getc(IN);
if (c == EOF) {
return OPJ_FALSE;
}
}
}
}
......
......@@ -568,7 +568,8 @@ int imagetotif(opj_image_t * image, const char *outfile)
{
TIFF *tif;
tdata_t buf;
uint32 width, height, bps, tiPhoto;
uint32 width, height;
uint16 bps, tiPhoto;
int adjust, sgnd;
int64_t strip_size, rowStride, TIFF_MAX;
OPJ_UINT32 i, numcomps;
......@@ -577,7 +578,7 @@ int imagetotif(opj_image_t * image, const char *outfile)
convert_32s_PXCX cvtPxToCx = NULL;
convert_32sXXx_C1R cvt32sToTif = NULL;
bps = (uint32)image->comps[0].prec;
bps = (uint16)image->comps[0].prec;
planes[0] = image->comps[0].data;
numcomps = image->numcomps;
......@@ -692,7 +693,7 @@ int imagetotif(opj_image_t * image, const char *outfile)
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, (uint32)numcomps);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, (uint16)numcomps);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
......@@ -1253,8 +1254,8 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
OPJ_COLOR_SPACE color_space = OPJ_CLRSPC_UNKNOWN;
opj_image_cmptparm_t cmptparm[4]; /* RGBA */
opj_image_t *image = NULL;
int has_alpha = 0;
uint32 tiBps, tiPhoto, tiSf, tiSpp, tiPC, tiWidth, tiHeight;
uint16 tiBps, tiPhoto, tiSf, tiSpp, tiPC;
uint32 tiWidth, tiHeight;
OPJ_BOOL is_cinema = OPJ_IS_CINEMA(parameters->rsiz);
convert_XXx32s_C1R cvtTifTo32s = NULL;
convert_32s_CXPX cvtCxToPx = NULL;
......@@ -1355,34 +1356,6 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
break;
}
{/* From: tiff-4.0.x/libtiff/tif_getimage.c : */
uint16* sampleinfo;
uint16 extrasamples;
TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
&extrasamples, &sampleinfo);
if (extrasamples >= 1) {
switch (sampleinfo[0]) {
case EXTRASAMPLE_UNSPECIFIED:
/* Workaround for some images without correct info about alpha channel
*/
if (tiSpp > 3) {
has_alpha = 1;
}
break;
case EXTRASAMPLE_ASSOCALPHA: /* data pre-multiplied */
case EXTRASAMPLE_UNASSALPHA: /* data not pre-multiplied */
has_alpha = 1;
break;
}
} else /* extrasamples == 0 */
if (tiSpp == 4 || tiSpp == 2) {
has_alpha = 1;
}
}
/* initialize image components */
memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
......@@ -1396,11 +1369,10 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
is_cinema = 0U;
}
numcomps = tiSpp;
if (tiPhoto == PHOTOMETRIC_RGB) { /* RGB(A) */
numcomps = 3 + has_alpha;
color_space = OPJ_CLRSPC_SRGB;
} else if (tiPhoto == PHOTOMETRIC_MINISBLACK) { /* GRAY(A) */
numcomps = 1 + has_alpha;
color_space = OPJ_CLRSPC_GRAY;
}
......
......@@ -169,7 +169,7 @@ static void encode_help_display(void)
fprintf(stdout, " Different compression ratios for successive layers.\n");
fprintf(stdout,
" The rate specified for each quality level is the desired\n");
fprintf(stdout, " compression factor.\n");
fprintf(stdout, " compression factor (use 1 for lossless)\n");
fprintf(stdout, " Decreasing ratios required.\n");
fprintf(stdout, " Example: -r 20,10,1 means \n");
fprintf(stdout, " quality layer 1: compress 20x, \n");
......@@ -178,7 +178,8 @@ static void encode_help_display(void)
fprintf(stdout, " Options -r and -q cannot be used together.\n");
fprintf(stdout, "-q <psnr value>,<psnr value>,<psnr value>,...\n");
fprintf(stdout, " Different psnr for successive layers (-q 30,40,50).\n");
fprintf(stdout, " Increasing PSNR values required.\n");
fprintf(stdout, " Increasing PSNR values required, except 0 which can\n");
fprintf(stdout, " be used for the last layer to indicate it is lossless.\n");
fprintf(stdout, " Options -r and -q cannot be used together.\n");
fprintf(stdout, "-n <number of resolutions>\n");
fprintf(stdout, " Number of resolutions.\n");
......@@ -907,8 +908,9 @@ static int parse_cmdline_encoder(int argc, char **argv,
case 'b': { /* code-block dimension */
int cblockw_init = 0, cblockh_init = 0;
sscanf(opj_optarg, "%d,%d", &cblockw_init, &cblockh_init);
if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024
|| cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {
if (cblockw_init > 1024 || cblockw_init < 4 ||
cblockh_init > 1024 || cblockh_init < 4 ||
cblockw_init * cblockh_init > 4096) {
fprintf(stderr,
"!! Size of code_block error (option -b) !!\n\nRestriction :\n"
" * width*height<=4096\n * 4<=width,height<= 1024\n\n");
......@@ -1618,9 +1620,12 @@ static int parse_cmdline_encoder(int argc, char **argv,
return 1;
} /* mod fixed_quality */
/* if no rate entered, lossless by default */
/* Note: post v2.2.0, this is no longer necessary, but for released */
/* versions at the time of writing, this is needed to avoid crashes */
if (parameters->tcp_numlayers == 0) {
parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */
parameters->tcp_rates[0] = 0;
parameters->tcp_numlayers++;
parameters->cp_disto_alloc = 1;
}
......
......@@ -152,6 +152,10 @@ typedef struct opj_decompress_params {
int num_threads;
/* Quiet */
int quiet;
/** number of components to decode */
OPJ_UINT32 numcomps;
/** indices of components to decode */
OPJ_UINT32* comps_indices;
} opj_decompress_parameters;
/* -------------------------------------------------------------------------- */
......@@ -227,6 +231,10 @@ static void decode_help_display(void)
" If 'C' is specified (default), values are clipped.\n"
" If 'S' is specified, values are scaled.\n"
" A 0 value can be specified (meaning original bit depth).\n");
fprintf(stdout, " -c first_comp_index[,second_comp_index][,...]\n"
" OPTIONAL\n"
" To limit the number of components to decoded.\n"
" Component indices are numbered starting at 0.\n");
fprintf(stdout, " -force-rgb\n"
" Force output image colorspace to RGB\n"
" -upsample\n"
......@@ -560,7 +568,7 @@ int parse_cmdline_decoder(int argc, char **argv,
{"quiet", NO_ARG, NULL, 1},
};
const char optlist[] = "i:o:r:l:x:d:t:p:"
const char optlist[] = "i:o:r:l:x:d:t:p:c:"
/* UniPG>> */
#ifdef USE_JPWL
......@@ -770,6 +778,25 @@ int parse_cmdline_decoder(int argc, char **argv,
return 1;
}
}
break;
/* ----------------------------------------------------- */
case 'c': { /* Componenets */
const char* iter = opj_optarg;