jsjpeg.js
/**
 * Parse Start of Sequence marker
 * 
 * @param {String} marker Name of the segment
 * @param {DataViewReader} reader 
 */
Parse Start of Sequence marker

@param {String} marker Name of the segment
@param {DataViewReader} reader
Parse Start of Sequence marker @param { String } marker Name of the segment @param { DataViewReader } reader
function decodeScan(marker, reader, img, scan) {
    scan.dcpred = [];
    let idctType = document.querySelector('input[name="idctType"]:checked').value;
    switch(idctType) {
        case "calculated":  idctFn = idct;          break;
        case "cached":      idctFn = idctCached;    break;
        case "chenwang":    idctFn = idctChenWang;  break;
        default:
            console.log(`Warning: unknown IDCT type ${idctType}`);
            idctFn = idct;
    }
    let colorConvFn;
    let colorConvType = document.querySelector('input[name="colorConvType"]:checked').value;
    switch(colorConvType) {
        case "float":       colorConvFn = YCbCrToRGB;       break;
        case "integer":     colorConvFn = YCbCrToRGBInt;    break;
        default:
            console.log(`Warning: unknown colorspace conversion type ${colorConvType}`);
            colorConvFn = YCbCrToRGB;
    }
    let components = [];
    for (selector of scan.components) {
        for (imgComponent of img.frame.components) {
            let id = imgComponent.componentID;
            if (id === selector[0]) {
                components.push(imgComponent);
                scan.dcpred[id] = 0;    
                break;
            }
        }
    }
    scan.orderedComponents = components;
    let mcuIndex = 0;
    for (let v = 0; v < img.frame.vMCUS; v++) {
        for (let h = 0; h < img.frame.hMCUs; h++) {
            if (img.restartInterval > 0 && mcuIndex > 0 && (mcuIndex % img.restartInterval) === 0) {
                let byte = reader.nextByte();
                if (byte != 0xFF) {
                    console.error("Expected 0xFF when looking for restart marker, found "
                        + byte.toString(16));
                }
                byte = reader.nextByte();
                if (byte >= 0xD0 && byte <= 0xD7) {
                } else {
                    console.error("Found unexpected marker when looking for reset: " + byte.toString(16));
                }
                scan.dcpred.fill(0);
                reader.align();     
            }
            decodeMCU(reader, img, scan, v, h);
            mcuIndex++;
        }
    }
    for (component of components) {
        drawComponent(component);
        scaleComponent(component);
        drawComponentFullSize(component);
    }
    combineComponents(components, colorConvFn);
    document.getElementById("outputhsize").textContent = img.frame.outputX;
    document.getElementById("outputvsize").textContent = img.frame.outputY;
}
function decodeScan ( marker , reader , img , scan ) { scan . dcpred = [ ] ; let idctType = document . querySelector ( 'input[name="idctType"]:checked' ) . value ; switch ( idctType ) { case "calculated" : idctFn = idct ; break ; case "cached" : idctFn = idctCached ; break ; case "chenwang" : idctFn = idctChenWang ; break ; default : console . log ( ` ${ idctType } ` ) ; idctFn = idct ; } let colorConvFn ; let colorConvType = document . querySelector ( 'input[name="colorConvType"]:checked' ) . value ; switch ( colorConvType ) { case "float" : colorConvFn = YCbCrToRGB ; break ; case "integer" : colorConvFn = YCbCrToRGBInt ; break ; default : console . log ( ` ${ colorConvType } ` ) ; colorConvFn = YCbCrToRGB ; } let components = [ ] ; for ( selector of scan . components ) { for ( imgComponent of img . frame . components ) { let id = imgComponent . componentID ; if ( id === selector [ 0 ] ) { components . push ( imgComponent ) ; scan . dcpred [ id ] = 0 ; break ; } } } scan . orderedComponents = components ; let mcuIndex = 0 ; for ( let v = 0 ; v < img . frame . vMCUS ; v ++ ) { for ( let h = 0 ; h < img . frame . hMCUs ; h ++ ) { if ( img . restartInterval > 0 && mcuIndex > 0 && ( mcuIndex % img . restartInterval ) === 0 ) { let byte = reader . nextByte ( ) ; if ( byte != 0xFF ) { console . error ( "Expected 0xFF when looking for restart marker, found " + byte . toString ( 16 ) ) ; } byte = reader . nextByte ( ) ; if ( byte >= 0xD0 && byte <= 0xD7 ) { } else { console . error ( "Found unexpected marker when looking for reset: " + byte . toString ( 16 ) ) ; } scan . dcpred . fill ( 0 ) ; reader . align ( ) ; } decodeMCU ( reader , img , scan , v , h ) ; mcuIndex ++ ; } } for ( component of components ) { drawComponent ( component ) ; scaleComponent ( component ) ; drawComponentFullSize ( component ) ; } combineComponents ( components , colorConvFn ) ; document . getElementById ( "outputhsize" ) . textContent = img . frame . outputX ; document . getElementById ( "outputvsize" ) . textContent = img . frame . outputY ; }
Parse Start of Sequence marker
Parse Start of Sequence marker
// Scratch space for DC predictor. Indexed by component ID (therefore usually 1-indexed) // Choose IDCT function // Choose colorspace conversion function // Order components in order specified by scan selector (B.2.3) // Reset DC pred for each component (E.2.4) // Image components in the order specified by the scan selector // Note: data is always interleaved if there is more than 1 component (A.2) // Read compressed data; decode it.... // console.log("Decoding MCU " + mcuIndex); // Look for a restart marker; file is likely corrupt if we don't find one // console.log("Restart marker " + byte.toString(16) + ", resetting decoder"); // Found restart marker, so reset decoder (F.2.1.3.1) // Align to the next byte // Draw the components at their native size, then scale up to the image's size, // then draw the components at the image's size. Finally, convert the components // to RGB and draw the combined image to the page.