DrKLO/Telegram · error

%s: transformation is not perfect

Error message

%s: transformation is not perfect

What it means

When the -perfect flag is set, jpegtran calls jtransform_request_workspace at jpegtran.c:578. If this returns FALSE, the requested transformation (rotate, flip, crop, transpose) cannot be applied losslessly because the image dimensions are not compatible with the transform's block-alignment requirements. The -perfect flag makes this a hard failure rather than a silent trim.

Source

Thrown at TMessagesProj/jni/mozjpeg/jpegtran.c:579

    jpeg_mem_src(&srcinfo, inbuffer, insize);
  } else
#endif
  jpeg_stdio_src(&srcinfo, fp);

  /* Enable saving of extra markers that we want to copy */
  jcopy_markers_setup(&srcinfo, copyoption);

  /* Read file header */
  (void)jpeg_read_header(&srcinfo, TRUE);

  /* Any space needed by a transform option must be requested before
   * jpeg_read_coefficients so that memory allocation will be done right.
   */
#if TRANSFORMS_SUPPORTED
  /* Fail right away if -perfect is given and transformation is not perfect.
   */
  if (!jtransform_request_workspace(&srcinfo, &transformoption)) {
    fprintf(stderr, "%s: transformation is not perfect\n", progname);
    exit(EXIT_FAILURE);
  }
#endif

  /* Read source file as DCT coefficients */
  src_coef_arrays = jpeg_read_coefficients(&srcinfo);

  /* Initialize destination compression parameters from source values */
  jpeg_copy_critical_parameters(&srcinfo, &dstinfo);

  /* Adjust destination parameters if required by transform options;
   * also find out which set of coefficient arrays will hold the output.
   */
#if TRANSFORMS_SUPPORTED
  dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo,
                                                 src_coef_arrays,
                                                 &transformoption);
#else

View on GitHub (pinned to 45ab8f4308)

Solutions

  1. Remove the -perfect flag to allow jpegtran to trim edges automatically (lossy trim)
  2. Adjust the transform to match block boundaries: crop to multiples of 16 (or 8 for non-progressive)
  3. Pad or pre-resize the image so dimensions are multiples of the MCU size before transforming

Example fix

// before
jpegtran -perfect -rotate 90 input.jpg -outfile out.jpg

// after
// remove -perfect to allow trimming
jpegtran -rotate 90 input.jpg -outfile out.jpg
// or align crop to 16-pixel boundary
jpegtran -perfect -crop 1920x1080+0+0 input.jpg -outfile out.jpg
Defensive patterns

Strategy: validation

Validate before calling

// Read JPEG dimensions and check MCU alignment before invoking jpegtran -perfect
#include "jpeglib.h"
int transform_is_safe(const char *path, int transform_type) {
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);
    FILE *f = fopen(path, "rb");
    if (!f) { jpeg_destroy_decompress(&cinfo); return -1; }
    jpeg_stdio_src(&cinfo, f);
    jpeg_read_header(&cinfo, TRUE);
    int w = cinfo.image_width, h = cinfo.image_height;
    int block = cinfo.progressive_mode ? 16 : 8;
    fclose(f); jpeg_destroy_decompress(&cinfo);
    // for rotate 90: width must be multiple of block
    // for flip: the flipped dimension must be multiple of block
    // for crop: all offsets/dims must be multiples of block
    if (transform_type == ROTATE_90 || transform_type == ROTATE_270)
        return (w % block == 0) ? 0 : -1;
    if (transform_type == FLIP_H)
        return (w % block == 0) ? 0 : -1;
    if (transform_type == FLIP_V)
        return (h % block == 0) ? 0 : -1;
    return 0;
}

Prevention

When it happens

Trigger: Rotating a non-square JPEG with -rotate 90 -perfect when width is not a multiple of the MCU height. Cropping with -crop when the target dimensions don't align to JPEG block boundaries (multiples of 8 or 16). Flipping an image whose dimensions aren't multiples of the block size.

Common situations: User adds -perfect to guarantee lossless output but the source image has odd dimensions (e.g. 1921x1080). Automated pipeline that always includes -perfect but processes images with varying dimensions. A crop region that doesn't start/end on block boundaries.

Related errors


AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14). Data as JSON: /api/errors/2ebd615e479a4965. Report an issue: GitHub.