private void DecodeScan(byte numberOfComponents, byte[] componentSelector, int resetInterval, JPEGBinaryReader jpegReader, ref byte marker) { //TODO: not necessary jpegReader.eob_run = 0; int mcuIndex = 0; int mcuTotalIndex = 0; // This loops through until a MarkerTagFound exception is // found, if the marker tag is a RST (Restart Marker) it // simply skips it and moves on this system does not handle // corrupt data streams very well, it could be improved by // handling misplaced restart markers. int h = 0, v = 0; int x = 0; long lastPosition = jpegReader.BaseStream.Position; //TODO: replace this with a loop which knows how much data to expect while (true) { #region Inform caller of decode progress if (ProgressUpdateMethod != null) { if (jpegReader.BaseStream.Position >= lastPosition + JpegDecoder.ProgressUpdateByteInterval) { lastPosition = jpegReader.BaseStream.Position; ProgressUpdateMethod(lastPosition); } } #endregion try { // Loop though capturing MCU, instruct each // component to read in its necessary count, for // scaling factors the components automatically // read in how much they need // Sec A.2.2 from CCITT Rec. T.81 (1992 E) bool interleaved = !(numberOfComponents == 1); if (!interleaved) { JpegComponent comp = Scan.GetComponentById(componentSelector[0]); comp.SetBlock(mcuIndex); comp.DecodeMCU(jpegReader, h, v); int mcus_per_line = mcus_per_row(comp); int blocks_per_line = (int)Math.Ceiling((double)this.Width / (8 * comp.factorH)); // TODO: Explain the non-interleaved scan ------ h++; x++; if (h == comp.factorH) { h = 0; mcuIndex++; } if ((x % mcus_per_line) == 0) { x = 0; v++; if (v == comp.factorV) { if (h != 0) { mcuIndex++; h = 0; } v = 0; } else { mcuIndex -= blocks_per_line; // we were mid-block if (h != 0) { mcuIndex++; h = 0; } } } // ----------------------------------------------- } else // Components are interleaved { for (int compIndex = 0; compIndex < numberOfComponents; compIndex++) { JpegComponent comp = Scan.GetComponentById(componentSelector[compIndex]); comp.SetBlock(mcuTotalIndex); for (int j = 0; j < comp.factorV; j++) { for (int i = 0; i < comp.factorH; i++) { comp.DecodeMCU(jpegReader, i, j); } } } mcuIndex++; mcuTotalIndex++; } } // We've found a marker, see if the marker is a restart // marker or just the next marker in the stream. If // it's the next marker in the stream break out of the // while loop, if it's just a restart marker skip it catch (JPEGMarkerFoundException ex) { marker = ex.Marker; // Handle JPEG Restart Markers, this is where the // count of MCU's per interval is compared with // the count actually obtained, if it's short then // pad on some MCU's ONLY for components that are // greater than one. Also restart the DC prediction // to zero. if (marker == JPEGMarker.RST0 || marker == JPEGMarker.RST1 || marker == JPEGMarker.RST2 || marker == JPEGMarker.RST3 || marker == JPEGMarker.RST4 || marker == JPEGMarker.RST5 || marker == JPEGMarker.RST6 || marker == JPEGMarker.RST7) { for (int compIndex = 0; compIndex < numberOfComponents; compIndex++) { JpegComponent comp = Scan.GetComponentById(componentSelector[compIndex]); if (compIndex > 1) { comp.padMCU(mcuTotalIndex, resetInterval - mcuIndex); } comp.resetInterval(); } mcuTotalIndex += (resetInterval - mcuIndex); mcuIndex = 0; } else { break; // We're at the end of our scan, exit out. } } } }
public void DecodeScan(byte numberOfComponents, byte[] componentSelector, int resetInterval, JPEGBinaryReader jpegReader, ref byte marker) { jpegReader.eob_run = 0; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; long position = jpegReader.BaseStream.Position; while (true) { if (ProgressUpdateMethod != null && jpegReader.BaseStream.Position >= position + JpegDecoder.ProgressUpdateByteInterval) { position = jpegReader.BaseStream.Position; ProgressUpdateMethod(position); } try { if (numberOfComponents == 1) { JpegComponent componentById = Scan.GetComponentById(componentSelector[0]); componentById.SetBlock(num); componentById.DecodeMCU(jpegReader, num3, num4); int num6 = mcus_per_row(componentById); int num7 = (int)Math.Ceiling((double)(int)Width / (double)(8 * componentById.factorH)); num3++; num5++; if (num3 == componentById.factorH) { num3 = 0; num++; } if (num5 % num6 == 0) { num5 = 0; num4++; if (num4 == componentById.factorV) { if (num3 != 0) { num++; num3 = 0; } num4 = 0; } else { num -= num7; if (num3 != 0) { num++; num3 = 0; } } } } else { for (int i = 0; i < numberOfComponents; i++) { JpegComponent componentById2 = Scan.GetComponentById(componentSelector[i]); componentById2.SetBlock(num2); for (int j = 0; j < componentById2.factorV; j++) { for (int k = 0; k < componentById2.factorH; k++) { componentById2.DecodeMCU(jpegReader, k, j); } } } num++; num2++; } } catch (JPEGMarkerFoundException ex) { marker = ex.Marker; if (marker != 208 && marker != 209 && marker != 210 && marker != 211 && marker != 212 && marker != 213 && marker != 214 && marker != 215) { return; } for (int l = 0; l < numberOfComponents; l++) { JpegComponent componentById3 = Scan.GetComponentById(componentSelector[l]); if (l > 1) { componentById3.padMCU(num2, resetInterval - num); } componentById3.resetInterval(); } num2 += resetInterval - num; num = 0; } } }