dataUnits = null;
ImageData[] loadFromByteStream() {	JPEGStartOfImage soi = new JPEGStartOfImage(inputStream);	if (!soi.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);	restartInterval = 0;	/* Process the tables preceding the frame header. */	processTables();		/* Start of Frame. */	frameHeader = new JPEGFrameHeader(inputStream);	if (!frameHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);	imageWidth = frameHeader.getSamplesPerLine();	imageHeight = frameHeader.getNumberOfLines();	maxH = frameHeader.getMaxHFactor();	maxV = frameHeader.getMaxVFactor();	int mcuWidth = maxH * DCTSIZE;	int mcuHeight = maxV * DCTSIZE;	interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth;	interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight;	progressive = frameHeader.isProgressive();	samplePrecision = frameHeader.getSamplePrecision();	nComponents = frameHeader.getNumberOfImageComponents();	frameComponents = frameHeader.componentParameters;	componentIds = frameHeader.componentIdentifiers;	imageComponents = new byte[nComponents][];	if (progressive) {		// Progressive jpeg: need to keep all of the data units.		dataUnits = new int[nComponents][][];	} else {		// Sequential jpeg: only need one data unit.		dataUnit = new int[8 * 8];	}	for (int i = 0; i < nComponents; i++) {		int[] frameComponent = frameComponents[componentIds[i]];		int bufferSize = frameComponent[CW] * frameComponent[CH];		imageComponents[i] = new byte[bufferSize];		if (progressive) {			dataUnits[i] = new int[bufferSize][];		}	}	/* Process the tables preceding the scan header. */	processTables();		/* Start of Scan. */	scanHeader = new JPEGScanHeader(inputStream);	if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);		/* Process scan(s) and further tables until EOI. */	int progressiveScanCount = 0;	boolean done = false;	while(!done) {		resetInputBuffer();		precedingDCs = new int[4];		decodeScan();		if (progressive && loader.hasListeners()) {			ImageData imageData = createImageData();			loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, false));			progressiveScanCount++;		}		/* Unread any buffered data before looking for tables again. */		int delta = 512 - bufferCurrentPosition - 1;		if (delta > 0) {			byte[] unreadBuffer = new byte[delta];			System.arraycopy(dataBuffer, bufferCurrentPosition + 1, unreadBuffer, 0, delta);			try {				inputStream.unread(unreadBuffer);			} catch (IOException e) {				SWT.error(SWT.ERROR_IO, e);			}		}				/* Process the tables preceding the next scan header. */		JPEGSegment jpegSegment = processTables();		if (jpegSegment == null || jpegSegment.getSegmentMarker() == EOI) {			done = true;		} else {			scanHeader = new JPEGScanHeader(inputStream);			if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);		}	}		if (progressive) {		for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) {			for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) {				for (int iComp = 0; iComp < nComponents; iComp++) {					int[] frameComponent = frameComponents[componentIds[iComp]];					int hi = frameComponent[HI];					int vi = frameComponent[VI];					int compWidth = frameComponent[CW];					for (int ivi = 0; ivi < vi; ivi++) {						for (int ihi = 0; ihi < hi; ihi++) {							int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi;							dataUnit = dataUnits[iComp][index];							dequantize(dataUnit, iComp);							inverseDCT(dataUnit);							storeData(dataUnit, iComp, xmcu, ymcu, hi, ihi, vi, ivi);						}					}				}			}		}	}	ImageData imageData = createImageData();	if (progressive && loader.hasListeners()) {		loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, true));	}	return new ImageData[] {imageData};}