<?php 
 
include('class.jpeg_decoder.php'); 
 
$inputFile = "./input.jpg"; // Replace with your input file path 
$jpeg_decoder_output_png = './output.png'; 
 
echo "<html><head><title>PHP JPEG Decoder Test</title></head><body>"; 
echo "<p>This is an experimental JPEG encoder and decoder ported to PHP from the JavaScript JPEG codec.</p> 
<h1>Decoding: " . htmlspecialchars($inputFile) . "</h1>"; 
echo "<hr>"; 
echo "<h2>Decoder Output:</h2>"; 
echo "<pre style='background-color:#f0f0f0; border:1px solid #ccc; padding: 10px; max-height: 300px; overflow-y: scroll;'>"; 
 
try { 
    // --- Run the Decoder --- 
    list($frame, $jfif, $adobe, $components, $comments) = read_image_file($inputFile); 
 
    echo "</pre>"; // End decoder output pre block 
    echo "<hr>"; 
    echo "<h2>Image Details:</h2>"; 
    echo "<ul>"; 
    echo "<li>Dimensions: {$frame['samplesPerLine']} x {$frame['scanLines']}</li>"; 
    echo "<li>Precision: {$frame['precision']} bits</li>"; 
    echo "<li>Mode: " . ($frame['baseline'] ? 'Baseline' : ($frame['progressive'] ? 'Progressive' : ($frame['extended'] ? 'Extended Sequential' : 'Unknown'))) . " (SOF Marker: 0x" . dechex($frame['type']) . ")</li>"; 
    echo "<li>Components: " . count($frame['components']) . "</li>"; 
    if ($jfif) echo "<li>JFIF Version: {$jfif['version']['major']}.{$jfif['version']['minor']}</li>"; 
    if ($adobe) echo "<li>Adobe Marker Found: Yes (Transform: {$adobe['transformCode']})</li>"; 
    if ($comments) echo "<li>Comments: " . count($comments) . "</li>"; 
    echo "</ul>"; 
 
 
    // --- Prepare for Image Output --- 
    $width = $frame['samplesPerLine']; 
    $height = $frame['scanLines']; 
 
    echo "<hr><h2>Processing Component Data for Output:</h2><pre>"; 
    // Combine components into RGBA pixel data using getData 
    $pixelDataRGBA = getData($components, $width, $height, $adobe); 
    echo "</pre>"; 
 
 
    // Prepare imageData structure (though copyToImageData doesn't strictly need it now) 
    $imageData = [ 
        'width' => $width, 
        'height' => $height, 
        'data' => [] // Will be filled by copyToImageData (or directly assign $pixelDataRGBA) 
    ]; 
    // Copy (or just assign) the RGBA data 
    $imageData['data'] = $pixelDataRGBA; 
 
 
    // --- Create image with GD library --- 
     echo "<hr><h2>Creating PNG with GD:</h2>"; 
    $image = imagecreatetruecolor($width, $height); 
    if (!$image) { 
        throw new Exception("GD: imagecreatetruecolor failed."); 
    } 
    // Enable alpha blending for transparency handling if needed (usually not for JPEG) 
    imagealphablending($image, true); // Blend alpha channel 
    imagesavealpha($image, true); // Save full alpha channel 
 
    $pixelIndex = 0; 
    for ($y = 0; $y < $height; $y++) { 
        for ($x = 0; $x < $width; $x++) { 
            if (!isset($imageData['data'][$pixelIndex+3])) { 
                 // Data array might be shorter than expected if getData had issues 
                 echo "<p>Warning: Ran out of pixel data at ($x, $y)</p>"; 
                 // Set pixel to black or break? Let's set to magenta for visibility 
                 $color = imagecolorallocatealpha($image, 255, 0, 255, 0); // Opaque magenta 
                 imagesetpixel($image, $x, $y, $color); 
                 // Ensure pixelIndex advances correctly even on error if we continue 
                 $pixelIndex += 4; // Move past the expected RGBA group 
                 continue; // Skip to next pixel 
            } 
            $r = $imageData['data'][$pixelIndex++]; 
            $g = $imageData['data'][$pixelIndex++]; 
            $b = $imageData['data'][$pixelIndex++]; 
            $a_byte = $imageData['data'][$pixelIndex++]; // Alpha 0-255 
 
            // GD alpha is 0 (opaque) to 127 (transparent) 
            $a_gd = floor((127 * (255 - $a_byte)) / 255); // Convert 0-255 alpha to 0-127 GD alpha 
            $a_gd = max(0, min(127, $a_gd)); // Clamp just in case 
 
            $color = imagecolorallocatealpha($image, $r, $g, $b, $a_gd); 
            if ($color === false) { 
                 echo "<p>Warning: GD: imagecolorallocatealpha failed for pixel ($x, $y) with RGBA($r, $g, $b, $a_byte). Setting black.</p>"; 
                 $color = imagecolorallocatealpha($image, 0, 0, 0, 0); // Fallback: opaque black 
            } 
            imagesetpixel($image, $x, $y, $color); 
        } 
    } 
    echo "<p>GD Image object created.</p>"; 
 
 
    // --- Save and Display --- 
    echo "<p>Saving PNG to: $jpeg_decoder_output_png</p>"; 
    $saveResult = imagepng($image, $jpeg_decoder_output_png); 
    if (!$saveResult) { 
         echo "<p><b>Error: Failed to save PNG image! Check permissions and GD installation.</b></p>"; 
    } else { 
        echo "<p>PNG saved successfully.</p>"; 
    } 
    imagedestroy($image); 
 
    echo "<hr><h2>Comparison:</h2>"; 
    echo "<h3>Original Input Image:</h3>"; 
    echo "<img src='" . htmlspecialchars($inputFile) . "' alt='Original JPEG' title='Original JPEG' style='max-width: 400px; border: 1px solid blue;'>"; 
    echo "<h3>Decoded Output Image (PNG):</h3>"; 
    if ($saveResult) { 
      echo "<img src='" . htmlspecialchars($jpeg_decoder_output_png) . "?t=" . time() . "' alt='Decoded PNG' title='Decoded PNG' style='max-width: 400px; border: 1px solid green;'>"; // Add timestamp to avoid caching 
    } else { 
      echo "<p>(Failed to save decoded image)</p>"; 
    } 
 
 
} catch (Exception $e) { 
    echo '</pre><hr><h2 style="color: red;">Caught exception:</h2><pre>'; 
    echo 'Message: ',  htmlspecialchars($e->getMessage()), "\n"; 
    echo 'File: ', $e->getFile(), "\n"; 
    echo 'Line: ', $e->getLine(), "\n"; 
    echo "\nStack trace:\n", htmlspecialchars($e->getTraceAsString()); 
    echo "</pre>"; 
} 
 
echo "</body></html>"; 
 
 |