This class defines a Buffered Random Access File. It implements the BinaryDataInput and BinaryDataOutput interfaces so that binary data input/output can be performed. This class is abstract since no assumption is done about the byte ordering type (little Endian, big Endian). So subclasses will have to implement methods like readShort(), writeShort(), readFloat(), ...

BufferedRandomAccessFile (BRAF for short) is a RandomAccessFile containing an extra buffer. When the BRAF is accessed, it checks if the requested part of the file is in the buffer or not. If that is the case, the read/write is done on the buffer. If not, the file is uppdated to reflect the current status of the buffer and the file is then accessed for a new buffer containing the requested byte/bit.

Inheritance: RandomAccessIO, EndianType
Beispiel #1
0
        /// <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++;
                }
            }
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        /// <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);
        }