← Back to team overview

debcrafters-packages team mailing list archive

[Bug 2127146] [NEW] jp2.c:831: opj_jp2_write_colr: Assertion `jp2->color.icc_profile_len' failed.

 

Public bug reported:

# OpenJPEG 2.5.0 ICC Profile Encoding Bug

## Summary
Assertion failure when encoding JPEG2000 (JP2) images with ICC profiles using `opj_image_t->icc_profile_buf/len`.

## Error
```
test: ./src/lib/openjp2/jp2.c:831: opj_jp2_write_colr: Assertion `jp2->color.icc_profile_len' failed.
Aborted (core dumped)
```

## Root Cause
In `opj_jp2_setup_encoder()` (jp2.c:~2001), when `image->icc_profile_len > 0`:
1. OpenJPEG sets `jp2->meth = 2` to indicate ICC profile method
2. BUT it does NOT copy ICC data from `opj_image_t` to `jp2->color`
3. This leaves `jp2->color.icc_profile_len = 0` while `jp2->meth = 2`

Later, in `opj_jp2_write_colr()` (jp2.c:831):
```c
switch (jp2->meth) {
case 2 :
    assert(jp2->color.icc_profile_len); /* <-- FAILS HERE */
    l_colr_size += jp2->color.icc_profile_len;
    break;
}
```

## Code Analysis

### jp2.c:2001 - opj_jp2_setup_encoder()
```c
/* Colour Specification box */
if (image->icc_profile_len) {
    jp2->meth = 2;           // <-- Sets method to ICC
    jp2->enumcs = 0;
} else {
    jp2->meth = 1;
    // ... enumerated colorspace
}
```

**Missing:** No code to copy `image->icc_profile_buf/len` to
`jp2->color.icc_profile_buf/len`

### For comparison - decoding path (jp2.c:~1655)
```c
if (jp2->color.icc_profile_buf) {
    p_image->icc_profile_buf = jp2->color.icc_profile_buf;
    p_image->icc_profile_len = jp2->color.icc_profile_len;
    jp2->color.icc_profile_buf = NULL;  // Transfer ownership
}
```

**Note:** Decoding works fine because it copies FROM `jp2->color` TO
`opj_image_t`.

## Minimal Reproduction

```c
#include <openjpeg.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    opj_image_cmptparm_t cmptparm[3] = {0};
    for (int i = 0; i < 3; ++i) {
        cmptparm[i].prec = 8;
        cmptparm[i].w = cmptparm[i].h = 256;
        cmptparm[i].dx = cmptparm[i].dy = 1;
    }

    opj_image_t *image = opj_image_create(3, cmptparm, OPJ_CLRSPC_SRGB);
    image->x1 = image->y1 = 256;

    // Set ICC profile
    static const unsigned char icc[] = "fake_icc_profile_data";
    image->icc_profile_buf = malloc(sizeof(icc));
    memcpy(image->icc_profile_buf, icc, sizeof(icc));
    image->icc_profile_len = sizeof(icc);

    opj_cparameters_t params;
    opj_set_default_encoder_parameters(&params);

    opj_codec_t *codec = opj_create_compress(OPJ_CODEC_JP2);
    opj_setup_encoder(codec, &params, image);  // <-- Sets jp2->meth=2 but doesn't copy ICC

    opj_stream_t *stream = opj_stream_create_default_file_stream("/tmp/test.jp2", OPJ_FALSE);
    opj_start_compress(codec, image, stream);  // <-- CRASHES HERE with assertion

    // Cleanup code...
    return 0;
}
```

**Compile:** `gcc test.c -I/usr/include/openjpeg-2.5 -lopenjp2`
**Result:** Aborted with assertion failure

## Expected Behavior
OpenJPEG should automatically copy ICC profile data from `opj_image_t->icc_profile_buf/len`
to `jp2->color.icc_profile_buf/len` during `opj_setup_encoder()` or `opj_start_compress()`.

** Affects: openjpeg2 (Ubuntu)
     Importance: Undecided
         Status: New

-- 
You received this bug notification because you are a member of
Debcrafters packages, which is subscribed to openjpeg2 in Ubuntu.
https://bugs.launchpad.net/bugs/2127146

Title:
  jp2.c:831: opj_jp2_write_colr: Assertion `jp2->color.icc_profile_len'
  failed.

Status in openjpeg2 package in Ubuntu:
  New

Bug description:
  # OpenJPEG 2.5.0 ICC Profile Encoding Bug

  ## Summary
  Assertion failure when encoding JPEG2000 (JP2) images with ICC profiles using `opj_image_t->icc_profile_buf/len`.

  ## Error
  ```
  test: ./src/lib/openjp2/jp2.c:831: opj_jp2_write_colr: Assertion `jp2->color.icc_profile_len' failed.
  Aborted (core dumped)
  ```

  ## Root Cause
  In `opj_jp2_setup_encoder()` (jp2.c:~2001), when `image->icc_profile_len > 0`:
  1. OpenJPEG sets `jp2->meth = 2` to indicate ICC profile method
  2. BUT it does NOT copy ICC data from `opj_image_t` to `jp2->color`
  3. This leaves `jp2->color.icc_profile_len = 0` while `jp2->meth = 2`

  Later, in `opj_jp2_write_colr()` (jp2.c:831):
  ```c
  switch (jp2->meth) {
  case 2 :
      assert(jp2->color.icc_profile_len); /* <-- FAILS HERE */
      l_colr_size += jp2->color.icc_profile_len;
      break;
  }
  ```

  ## Code Analysis

  ### jp2.c:2001 - opj_jp2_setup_encoder()
  ```c
  /* Colour Specification box */
  if (image->icc_profile_len) {
      jp2->meth = 2;           // <-- Sets method to ICC
      jp2->enumcs = 0;
  } else {
      jp2->meth = 1;
      // ... enumerated colorspace
  }
  ```

  **Missing:** No code to copy `image->icc_profile_buf/len` to
  `jp2->color.icc_profile_buf/len`

  ### For comparison - decoding path (jp2.c:~1655)
  ```c
  if (jp2->color.icc_profile_buf) {
      p_image->icc_profile_buf = jp2->color.icc_profile_buf;
      p_image->icc_profile_len = jp2->color.icc_profile_len;
      jp2->color.icc_profile_buf = NULL;  // Transfer ownership
  }
  ```

  **Note:** Decoding works fine because it copies FROM `jp2->color` TO
  `opj_image_t`.

  ## Minimal Reproduction

  ```c
  #include <openjpeg.h>
  #include <stdlib.h>
  #include <string.h>

  int main(void) {
      opj_image_cmptparm_t cmptparm[3] = {0};
      for (int i = 0; i < 3; ++i) {
          cmptparm[i].prec = 8;
          cmptparm[i].w = cmptparm[i].h = 256;
          cmptparm[i].dx = cmptparm[i].dy = 1;
      }

      opj_image_t *image = opj_image_create(3, cmptparm, OPJ_CLRSPC_SRGB);
      image->x1 = image->y1 = 256;

      // Set ICC profile
      static const unsigned char icc[] = "fake_icc_profile_data";
      image->icc_profile_buf = malloc(sizeof(icc));
      memcpy(image->icc_profile_buf, icc, sizeof(icc));
      image->icc_profile_len = sizeof(icc);

      opj_cparameters_t params;
      opj_set_default_encoder_parameters(&params);

      opj_codec_t *codec = opj_create_compress(OPJ_CODEC_JP2);
      opj_setup_encoder(codec, &params, image);  // <-- Sets jp2->meth=2 but doesn't copy ICC

      opj_stream_t *stream = opj_stream_create_default_file_stream("/tmp/test.jp2", OPJ_FALSE);
      opj_start_compress(codec, image, stream);  // <-- CRASHES HERE with assertion

      // Cleanup code...
      return 0;
  }
  ```

  **Compile:** `gcc test.c -I/usr/include/openjpeg-2.5 -lopenjp2`
  **Result:** Aborted with assertion failure

  ## Expected Behavior
  OpenJPEG should automatically copy ICC profile data from `opj_image_t->icc_profile_buf/len`
  to `jp2->color.icc_profile_buf/len` during `opj_setup_encoder()` or `opj_start_compress()`.

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/openjpeg2/+bug/2127146/+subscriptions



Follow ups