/// <summary> This method reads and buffers the tile headers, packet headers and /// packet data. /// /// </summary> /// <param name="fi">The file to read the headers and data from /// /// </param> /// <exception cref="IOException">If an I/O error ocurred. /// /// </exception> private void readAndBuffer(BufferedRandomAccessFile fi) { int p, prem, length, t, markIndex; // Buffer main header fi.seek(0); length = ((System.Int32) positions[0]) - 2; mainHeader = new byte[length]; fi.readFully(mainHeader, 0, length); markIndex = 0; for (t = 0; t < nt; t++) { prem = ppt[t]; packetHeaders[t] = new byte[prem][]; packetData[t] = new byte[prem][]; sopMarkSeg[t] = new byte[prem][]; // Read tile header length = positions[markIndex + 1] - positions[markIndex]; tileHeaders[t] = new byte[length]; fi.readFully(tileHeaders[t], 0, length); markIndex++; for (p = 0; p < prem; p++) { // Read packet header length = positions[markIndex + 1] - positions[markIndex]; if (tempSop) { // SOP marker is skipped length -= CSJ2K.j2k.codestream.Markers.SOP_LENGTH; fi.skipBytes(CSJ2K.j2k.codestream.Markers.SOP_LENGTH); } else { // SOP marker is read and buffered length -= CSJ2K.j2k.codestream.Markers.SOP_LENGTH; sopMarkSeg[t][p] = new byte[CSJ2K.j2k.codestream.Markers.SOP_LENGTH]; fi.readFully(sopMarkSeg[t][p], 0, CSJ2K.j2k.codestream.Markers.SOP_LENGTH); } if (!tempEph) { // EPH marker is kept in header length += CSJ2K.j2k.codestream.Markers.EPH_LENGTH; } packetHeaders[t][p] = new byte[length]; fi.readFully(packetHeaders[t][p], 0, length); markIndex++; // Read packet data length = positions[markIndex + 1] - positions[markIndex]; length -= CSJ2K.j2k.codestream.Markers.EPH_LENGTH; if (tempEph) { // EPH marker is used and is skipped fi.skipBytes(CSJ2K.j2k.codestream.Markers.EPH_LENGTH); } packetData[t][p] = new byte[length]; fi.readFully(packetData[t][p], 0, length); markIndex++; } } }
/// <summary> This method writes the new codestream to the file. /// /// </summary> /// <param name="fi">The file to write the new codestream to /// /// </param> /// <exception cref="IOException">If an I/O error ocurred. /// /// </exception> private void writeNewCodestream(BufferedRandomAccessFile fi) { int t, p, tp; // i removed int numTiles = tileParts.Length; int[][] packetHeaderLengths = new int[numTiles][]; for (int i2 = 0; i2 < numTiles; i2++) { packetHeaderLengths[i2] = new int[maxtp]; } byte[] temp; int length; // Write main header up to SOT marker fi.write(mainHeader, 0, mainHeader.Length); // If PPM used write all packet headers in PPM markers if (ppmUsed) { System.IO.MemoryStream ppmMarkerSegment = new System.IO.MemoryStream(); int numPackets; int totNumPackets; int ppmIndex = 0; int ppmLength; int pStart, pStop; int[] prem = new int[numTiles]; // Set number of remaining packets for (t = 0; t < numTiles; t++) { prem[t] = packetHeaders[t].Length; } // Calculate Nppm values for (tp = 0; tp < maxtp; tp++) { for (t = 0; t < numTiles; t++) { if (tileParts[t].Length > tp) { totNumPackets = packetHeaders[t].Length; // Calculate number of packets in this tilepart numPackets = (tp == tileParts[t].Length - 1)?prem[t]:pptp; pStart = totNumPackets - prem[t]; pStop = pStart + numPackets; // Calculate number of packet header bytes for this // tile part for (p = pStart; p < pStop; p++) packetHeaderLengths[t][tp] += packetHeaders[t][p].Length; prem[t] -= numPackets; } } } // Write first PPM marker ppmMarkerSegment.WriteByte((System.Byte) SupportClass.URShift(CSJ2K.j2k.codestream.Markers.PPM, 8)); ppmMarkerSegment.WriteByte((System.Byte) (CSJ2K.j2k.codestream.Markers.PPM & 0x00FF)); ppmMarkerSegment.WriteByte((System.Byte) 0); // Temporary Lppm value ppmMarkerSegment.WriteByte((System.Byte) 0); // Temporary Lppm value ppmMarkerSegment.WriteByte((System.Byte) 0); // zppm ppmLength = 3; ppmIndex++; // Set number of remaining packets for (t = 0; t < numTiles; t++) prem[t] = packetHeaders[t].Length; // Write all PPM markers and information for (tp = 0; tp < maxtp; tp++) { for (t = 0; t < numTiles; t++) { if (tileParts[t].Length > tp) { totNumPackets = packetHeaders[t].Length; // Calculate number of packets in this tilepart numPackets = (tp == tileParts[t].Length - 1)?prem[t]:pptp; pStart = totNumPackets - prem[t]; pStop = pStart + numPackets; // If Nppm value wont fit in current PPM marker segment // write current PPM marker segment and start new if (ppmLength + 4 > CSJ2K.j2k.codestream.Markers.MAX_LPPM) { // Write current PPM marker temp = ppmMarkerSegment.ToArray(); length = temp.Length - 2; temp[2] = (byte) (SupportClass.URShift(length, 8)); temp[3] = (byte) length; fi.write(temp, 0, length + 2); // Start new PPM marker segment //UPGRADE_ISSUE: Method 'java.io.ByteArrayOutputStream.reset' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javaioByteArrayOutputStreamreset'" //ppmMarkerSegment.reset(); ppmMarkerSegment.SetLength(0); ppmMarkerSegment.WriteByte((System.Byte) SupportClass.URShift(CSJ2K.j2k.codestream.Markers.PPM, 8)); ppmMarkerSegment.WriteByte((System.Byte) (CSJ2K.j2k.codestream.Markers.PPM & 0x00FF)); ppmMarkerSegment.WriteByte((System.Byte) 0); // Temporary Lppm value ppmMarkerSegment.WriteByte((System.Byte) 0); // Temporary Lppm value ppmMarkerSegment.WriteByte((System.Byte) ppmIndex++); // zppm ppmLength = 3; } // Write Nppm value length = packetHeaderLengths[t][tp]; ppmMarkerSegment.WriteByte((System.Byte) SupportClass.URShift(length, 24)); ppmMarkerSegment.WriteByte((System.Byte) SupportClass.URShift(length, 16)); ppmMarkerSegment.WriteByte((System.Byte) SupportClass.URShift(length, 8)); ppmMarkerSegment.WriteByte((System.Byte) length); ppmLength += 4; // Write packet headers for (p = pStart; p < pStop; p++) { length = packetHeaders[t][p].Length; // If next packet header value wont fit in // current PPM marker segment write current PPM // marker segment and start new if (ppmLength + length > CSJ2K.j2k.codestream.Markers.MAX_LPPM) { // Write current PPM marker temp = ppmMarkerSegment.ToArray(); length = temp.Length - 2; temp[2] = (byte) (SupportClass.URShift(length, 8)); temp[3] = (byte) length; fi.write(temp, 0, length + 2); // Start new PPM marker segment //UPGRADE_ISSUE: Method 'java.io.ByteArrayOutputStream.reset' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javaioByteArrayOutputStreamreset'" //ppmMarkerSegment.reset(); ppmMarkerSegment.SetLength(0); ppmMarkerSegment.WriteByte((System.Byte) SupportClass.URShift(CSJ2K.j2k.codestream.Markers.PPM, 8)); ppmMarkerSegment.WriteByte((System.Byte) (CSJ2K.j2k.codestream.Markers.PPM & 0x00FF)); ppmMarkerSegment.WriteByte((System.Byte) 0); // Temp Lppm value ppmMarkerSegment.WriteByte((System.Byte) 0); // Temp Lppm value ppmMarkerSegment.WriteByte((System.Byte) ppmIndex++); // zppm ppmLength = 3; } // write packet header ppmMarkerSegment.Write(packetHeaders[t][p], 0, packetHeaders[t][p].Length); ppmLength += packetHeaders[t][p].Length; } prem[t] -= numPackets; } } } // Write last PPM marker segment temp = ppmMarkerSegment.ToArray(); length = temp.Length - 2; temp[2] = (byte) (SupportClass.URShift(length, 8)); temp[3] = (byte) length; fi.write(temp, 0, length + 2); } // Write tile parts interleaved for (tp = 0; tp < maxtp; tp++) { for (t = 0; t < nt; t++) { if (tileParts[t].Length > tp) { temp = tileParts[t][tp]; length = temp.Length; fi.write(temp, 0, length); } } } fi.writeShort(CSJ2K.j2k.codestream.Markers.EOC); }
/// <summary> This method parses the codestream for SOT, SOP and EPH markers and /// removes header header bits signalling SOP and EPH markers if packed /// packet headers are used /// /// </summary> /// <param name="fi">The file to parse the markers from /// /// </param> /// <exception cref="IOException">If an I/O error ocurred. /// /// </exception> private void parseAndFind(BufferedRandomAccessFile fi) { int length, pos, i, t, sop = 0, eph = 0; short marker; int halfMarker; int tileEnd; System.Collections.Generic.List<System.Int32> markPos = new List<int>(10); // Find position of first SOT marker marker = (short) fi.readUnsignedShort(); // read SOC marker marker = (short) fi.readUnsignedShort(); while (marker != CSJ2K.j2k.codestream.Markers.SOT) { pos = fi.Pos; length = fi.readUnsignedShort(); // If SOP and EPH markers were only used for parsing in this // class remove SOP and EPH markers from Scod field if (marker == CSJ2K.j2k.codestream.Markers.COD) { int scod = fi.readUnsignedByte(); if (tempSop) scod &= 0xfd; // Remove bits indicating SOP if (tempEph) scod &= 0xfb; // Remove bits indicating SOP fi.seek(pos + 2); fi.write(scod); } fi.seek(pos + length); marker = (short) fi.readUnsignedShort(); } pos = fi.Pos; fi.seek(pos - 2); // Find all packet headers, packed data and tile headers for (t = 0; t < nt; t++) { // Read SOT marker fi.readUnsignedShort(); // Skip SOT pos = fi.Pos; markPos.Add((System.Int32) fi.Pos); fi.readInt(); // Skip Lsot and Isot length = fi.readInt(); // Read Psot fi.readUnsignedShort(); // Skip TPsot & TNsot tileEnd = pos + length - 2; // Last byte of tile // Find position of SOD marker marker = (short) fi.readUnsignedShort(); while (marker != CSJ2K.j2k.codestream.Markers.SOD) { pos = fi.Pos; length = fi.readUnsignedShort(); // If SOP and EPH markers were only used for parsing in this // class remove SOP and EPH markers from Scod field if (marker == CSJ2K.j2k.codestream.Markers.COD) { int scod = fi.readUnsignedByte(); if (tempSop) scod &= 0xfd; // Remove bits indicating SOP if (tempEph) scod &= 0xfb; // Remove bits indicating SOP fi.seek(pos + 2); fi.write(scod); } fi.seek(pos + length); marker = (short) fi.readUnsignedShort(); } // Find all SOP and EPH markers in tile sop = 0; eph = 0; i = fi.Pos; while (i < tileEnd) { halfMarker = (short) fi.readUnsignedByte(); if (halfMarker == (short) 0xff) { marker = (short) ((halfMarker << 8) + fi.readUnsignedByte()); i++; if (marker == CSJ2K.j2k.codestream.Markers.SOP) { markPos.Add((System.Int32) fi.Pos); ppt[t]++; sop++; fi.skipBytes(4); i += 4; } if (marker == CSJ2K.j2k.codestream.Markers.EPH) { markPos.Add((System.Int32) fi.Pos); eph++; } } i++; } } markPos.Add((System.Int32) (fi.Pos + 2)); positions = new System.Int32[markPos.Count]; markPos.CopyTo(positions); }