ADR-001: Image Scaling Behavior 

Status

Accepted

Date

2025-10-27

Authors

Development Team

Context

RTE CKEditor Image Extension for TYPO3

Context and Problem Statement 

The RTE CKEditor Image extension needs to provide flexible image processing options that balance quality, performance, and file size. Users need clear control over when images should be processed versus when original files should be used directly.

The system must handle various scenarios:

  • Different display quality requirements (web, retina displays, print)
  • Performance optimization (avoid unnecessary processing)
  • File size considerations (prevent serving oversized originals)
  • SVG handling (vector graphics don't need raster processing)

Decision Drivers 

  • User Control: Clear options for when to process vs use originals
  • Performance: Avoid unnecessary image processing operations
  • Quality: Provide appropriate quality for different use cases
  • File Size: Prevent serving excessively large files to browsers
  • Browser Compatibility: Ensure proper rendering across devices

Considered Options 

Option 1: Always Process Images 

  • Pros: Consistent behavior, predictable output
  • Cons: Unnecessary processing, performance overhead, potential quality loss

Option 2: Never Process Images (Always Use Originals) 

  • Pros: Maximum quality, no processing overhead
  • Cons: Large file sizes, no optimization for different displays

Option 3: Intelligent Conditional Processing (Selected) 

  • Pros: Balances quality, performance, and file size
  • Cons: More complex logic, requires configuration

Decision Outcome 

Chosen option: Option 3 - Intelligent Conditional Processing

The system implements a multi-tier approach with explicit user control and automatic optimization.

Image Processing Modes 

1. No Scaling (Skip Processing Entirely) 

Behavior: Use original file without any TYPO3 image processing

When to Use:

  • Newsletters (external email clients)
  • PDF generation
  • When maximum quality is required
  • When original file optimization is already optimal

Backend Attribute: data-noscale="1"

Example Scenario:

Original Image: 1920×1080 px (500 KB)
Display Size:   1920×1080 px
Processing:     NONE - original file used directly
Output URL:     /fileadmin/user_upload/image.jpg
Result:         Exact original file served (500 KB)
Copied!

Processing Info Message (Gray):

Processing Info: Image 1920×1080 px will be displayed at 1920×1080 px = ● Standard Quality (1.0x scaling)
Copied!

2. Low Quality (0.9x Multiplier) 

Behavior: Process with reduced quality for smaller file sizes

When to Use:

  • Thumbnail images
  • Background images where quality is less critical
  • Bandwidth-constrained scenarios

Example Scenario:

Original Image: 1920×1080 px
Display Size:   800×450 px
Multiplier:     0.9x
Calculation:    800×450 × 0.9 = 720×405 px
Processing:     YES - image scaled and compressed
Output URL:     /typo3temp/assets/processed/image_[hash].jpg
Result:         Processed file at 720×405 px
Copied!

Processing Info Message (Red):

Processing Info: Image 1920×1080 px will be resized to 720×405 px and displayed at 800×450 px = ● Low Quality (0.9x scaling)
Copied!

3. Standard Quality (1.0x Multiplier) 

Behavior: Process with exact display dimensions

When to Use:

  • General content images
  • Standard web displays (non-retina)
  • Balanced quality and file size

Example Scenario:

Original Image: 1920×1080 px
Display Size:   800×450 px
Multiplier:     1.0x
Calculation:    800×450 × 1.0 = 800×450 px
Processing:     YES - image scaled to exact display size
Output URL:     /typo3temp/assets/processed/image_[hash].jpg
Result:         Processed file at 800×450 px
Copied!

Processing Info Message (Orange):

Processing Info: Image 1920×1080 px will be resized to 800×450 px and displayed at 800×450 px = ● Standard Quality (1.0x scaling)
Copied!

4. Retina Quality (2.0x Multiplier) 

Behavior: Process with 2x display dimensions for high-DPI screens

When to Use:

  • Retina/HiDPI displays (MacBook, iPhone, modern monitors)
  • High-quality content imagery
  • Professional photography portfolios

Example Scenario:

Original Image: 1920×1500 px
Display Size:   960×750 px
Multiplier:     2.0x
Calculation:    960×750 × 2.0 = 1920×1500 px
Processing:     YES - image scaled for retina displays
Output URL:     /typo3temp/assets/processed/image_[hash].jpg
Result:         Processed file at 1920×1500 px
Copied!

Processing Info Message (Green):

Processing Info: Image 1920×1500 px will be resized to 1920×1500 px and displayed at 960×750 px = ● Retina Quality (2.0x scaling)
Copied!

5. Ultra Quality (3.0x Multiplier) 

Behavior: Process with 3x display dimensions for ultra-high-DPI

When to Use:

  • 4K/5K displays
  • Professional design work
  • Maximum quality requirements

Example Scenario:

Original Image: 5760×3240 px
Display Size:   640×360 px
Multiplier:     3.0x
Calculation:    640×360 × 3.0 = 1920×1080 px
Processing:     YES - image scaled for ultra displays
Output URL:     /typo3temp/assets/processed/image_[hash].jpg
Result:         Processed file at 1920×1080 px
Copied!

Processing Info Message (Cyan):

Processing Info: Image 5760×3240 px will be resized to 1920×1080 px and displayed at 640×360 px = ● Ultra Quality (3.0x scaling)
Copied!

6. Print Quality (6.0x Multiplier) 

Behavior: Process with 6x display dimensions for print output

When to Use:

  • Print-ready materials
  • High-resolution documents
  • Maximum quality print output

Example Scenario:

Original Image: 5760×3240 px
Display Size:   320×180 px
Multiplier:     6.0x
Calculation:    320×180 × 6.0 = 1920×1080 px
Processing:     YES - image scaled for print quality
Output URL:     /typo3temp/assets/processed/image_[hash].jpg
Result:         Processed file at 1920×1080 px
Copied!

Processing Info Message (Blue):

Processing Info: Image 5760×3240 px will be resized to 1920×1080 px and displayed at 320×180 px = ● Print Quality (6.0x scaling)
Copied!

Quality Calculation Logic 

Achievable Quality 

The system automatically determines what quality can actually be achieved based on the original image dimensions:

Quality Formula: actualQuality = min(imageWidth / displayWidth, imageHeight / displayHeight)

Examples:

  • Image 1920×1500, Display 960×750 → Quality = min(1920/960, 1500/750) = min(2.0, 2.0) = 2.0x (Retina)
  • Image 1920×1500, Display 192×150 → Quality = min(1920/192, 1500/150) = min(10.0, 10.0) = 10.0x (Print)
  • Image 1920×1500, Display 1920×1500 → Quality = min(1920/1920, 1500/1500) = min(1.0, 1.0) = 1.0x (Standard)
  • Image 1920×1500, Display 2840×3000 → Quality = min(1920/2840, 1500/3000) = min(0.68, 0.5) = 0.5x (Poor)

Processing Multipliers vs Achievable Quality 

When a processing option (Standard, Retina, Ultra, Print) is selected:

  • Requested Size = Display × Multiplier
  • Processed Size = min(Requested Size, Original Size) — Never upscale!
  • Actual Quality = Processed Size / Display Size

Example: Image 1920×1500, Display 1920×1500, Retina (2.0x)

  • Requested: 1920×1500 × 2.0 = 3840×3000
  • Processed: min(3840×3000, 1920×1500) = 1920×1500
  • Actual Quality: 1920/1920 = 1.0x (Standard, not Retina!)

Automatic Optimization Rules 

Rule 1: SVG Files (Always Skip Processing) 

Behavior: SVG files are NEVER processed regardless of settings

Rationale:

  • SVG is vector format that scales perfectly at any resolution
  • ImageMagick would rasterize SVG, losing vector benefits
  • Browser handles SVG scaling natively

Example:

File:           logo.svg (vector)
Display Size:   400×300 px
Setting:        ANY (ignored for SVG)
Processing:     NONE - original SVG used
Result:         Browser scales SVG natively
Copied!

Processing Info Message (Gray):

Processing Info: Vector image will not be processed (scales perfectly at any resolution).
Copied!

Rule 2: Dimensions Match Exactly (Skip Processing) 

Behavior: When display dimensions exactly match original, skip processing

Rationale:

  • No resize needed = no quality benefit from processing
  • Avoid unnecessary processing overhead
  • Preserve original file quality

Example:

Original Image: 1920×1080 px
Display Size:   1920×1080 px
Setting:        Standard (1.0x)
Processing:     NONE - dimensions match exactly
Result:         Original file used
Copied!

Processing Info Message (varies by scaling option):

No Scaling: Image 1920×1080 px will be displayed at 1920×1080 px = ● Standard Quality (1.0x scaling)
Standard (1.0x): Image 1920×1080 px will be displayed at 1920×1080 px = ● Standard Quality (1.0x scaling)
Retina (2.0x): Image 1920×1080 px will be displayed at 1920×1080 px = ● Standard Quality (1.0x scaling) [cannot achieve 2.0x]
Copied!

Note: When requested quality cannot be achieved (original image too small), the message shows the actual achievable quality.

Note: This rule is overridden by file size threshold (see Rule 4).

Rule 3: Display Exceeds Image Size (Skip Processing + Warning) 

Behavior: When display size is larger than original image, skip processing and warn

Rationale:

  • Upscaling degrades quality
  • Better to use original at natural size
  • User should be aware of quality limitation

Example:

Original Image: 800×600 px (small original)
Display Size:   1920×1080 px (larger than original)
Setting:        Retina (2.0x)
Processing:     NONE - cannot upscale quality
Result:         Original 800×600 px used, stretched by browser
Warning:        Quality degradation expected
Copied!

Processing Info Message (Red warning):

Processing Info: Image 800×600 px will be displayed at 1920×1080 px = ● Poor Quality (0.4x scaling)
Copied!

Rule 4: File Size Threshold (Force Processing) 

Behavior: Large files are processed even when dimensions match

Configuration:

lib.parseFunc_RTE.tags.img {
    noScale = 1
    noScale {
        maxFileSizeForAuto = 2000000  # 2MB threshold
    }
}
Copied!

Rationale:

  • Prevent serving multi-megabyte originals
  • Optimize file size through compression
  • Balance quality and bandwidth

Example:

Original Image: 1920×1080 px (5 MB uncompressed TIFF)
Display Size:   1920×1080 px (exact match)
File Size:      5,242,880 bytes (> 2MB threshold)
Processing:     YES - exceeds size threshold
Result:         Processed JPEG at 1920×1080 px (~500 KB)
Copied!

Frontend Rendering (ImageRenderingController) 

Processing Decision Logic 

protected function shouldSkipProcessing(
    File $originalFile,
    array $imageConfiguration,
    bool $noScale,
    int $maxFileSizeForAuto = 0
): bool {
    // RULE 1: SVG files - always skip
    if (strtolower($originalFile->getExtension()) === 'svg') {
        return true;
    }

    // RULE 2: Explicit noScale setting OR data-noscale attribute
    if ($noScale) {
        return true;
    }

    // Get dimensions
    $originalWidth = (int) ($originalFile->getProperty('width') ?? 0);
    $originalHeight = (int) ($originalFile->getProperty('height') ?? 0);
    $requestedWidth = (int) ($imageConfiguration['width'] ?? 0);
    $requestedHeight = (int) ($imageConfiguration['height'] ?? 0);

    // RULE 3: No dimensions requested - use original
    if ($requestedWidth === 0 && $requestedHeight === 0) {
        return true;
    }

    // RULE 4: Dimensions match exactly
    if ($requestedWidth === $originalWidth && $requestedHeight === $originalHeight) {
        // Check file size threshold
        if ($maxFileSizeForAuto > 0) {
            $fileSize = $originalFile->getSize();
            // Exceeds threshold - process to reduce size
            if ($fileSize > $maxFileSizeForAuto) {
                return false;
            }
        }
        // Within threshold or no limit - skip processing
        return true;
    }

    // Different dimensions - processing needed
    return false;
}
Copied!

Configuration Examples 

Global No Processing (All RTE Images) 

TypoScript Setup
# TypoScript Setup
lib.parseFunc_RTE.tags.img.noScale = 1
Copied!

Result: ALL images use originals, no processing

Selective No Processing (Per Image) 

Users set "No Scaling" option in image dialog.

Result: Only images with data-noscale="1" skip processing

File Size Optimized 

TypoScript Setup
lib.parseFunc_RTE.tags.img {
    noScale = 0  # Enable processing
    noScale {
        maxFileSizeForAuto = 2000000  # 2MB
    }
}
Copied!

Result: Images processed only when needed, automatic optimization for large files

User Interface Indicators 

Color Coding 

Quality Color Hex Usage
No Scaling Gray #6c757d No processing
Low Red #dc3545 Reduced quality
Standard Orange #ffc107 Balanced
Retina Green #28a745 High quality
Ultra Cyan #17a2b8 Ultra quality
Print Blue #007bff Print quality

Processing Info States 

  1. No Processing (Gray) - Original file used
  2. Normal Processing (Blue) - Standard resize operation
  3. Exact Match (Green) - No processing needed, dimensions match
  4. Oversized Display (Red) - Warning about quality limitation

Technical Implications 

Backend (SelectImageController) 

  • Validation: Enforce dimension limits (1-10000px) to prevent resource exhaustion
  • Security: Verify file access permissions (IDOR protection)
  • Performance: Use efficient file property access

Frontend (ImageRenderingController) 

  • Caching: Processed images cached in typo3temp/assets/
  • Security: Block non-public files from frontend rendering
  • Performance: Skip processing when possible to reduce server load

JavaScript (typo3image.js) 

  • Real-time Calculation: Show expected output dimensions
  • Visual Feedback: Color-coded quality indicators
  • Validation: Prevent invalid dimension combinations

Consequences 

Positive 

  • Flexibility: Users control when processing occurs
  • Performance: Automatic optimization reduces unnecessary operations
  • Quality: Appropriate processing for different use cases
  • File Size: Prevents serving oversized originals

Negative 

  • Complexity: More logic to maintain and test
  • Learning Curve: Users need to understand when to use each option
  • Edge Cases: Requires careful handling of dimension mismatches

Compliance 

  • TYPO3 Standards: Follows FAL (File Abstraction Layer) patterns
  • Security: Implements access control and resource limits
  • Performance: Optimizes for typical web usage patterns

References 

Revision History 

Date Version Changes
2025-10-27 1.0 Initial ADR documenting scaling behavior