rowBytes = 256 / 4 * 3 / 2;
    public boolean read(BinaryFile binFile) {        Compression compression;        LookupTable[] lookupTable = new LookupTable[4];        Image image;        int[][] indices = new int[6][6]; //ushort        int rowBytes;        int i, j, rc;        /* bool (uchar) */        /* all subframes present indicator */        boolean allSubframes;        long currentPos; // uint        long lookupOffsetTableOffset; // uint        int lookupTableOffsetRecLen; //ushort        long subframeMaskTableOffset; //uint        /* subframe offset (mask section) */        long[][] subframeOffset = new long[6][6];//uint[][]        /* for DCHUM */        long fsave; /* saved file loc */        int chummedSubframe; //uint        int attributeId; // ushort        int attributeParamId; //uchar        int tempc; //uchar        long attributeRecOffset; //uint        int numAttributeOffsetRecs; //ushort        int numSubframesChummed; //ushort        if (DEBUG_RPFDETAIL) {            Debug.output("ENTER RPFFRAME.READ");        }        try {            // Let's start at the beginning, shall we?            binFile.seek(0);            // Read the NITF part of the file...            nitfHeader = new NitfHeader();            // If false, it might not be a NITF file, start over...            if (!nitfHeader.read(binFile))                binFile.seek(0);            header = new RpfHeader();            // Now, read the RPF header...            if (!header.readHeader(binFile))                return false;            /* Check date for validity: date should be "1993xxxx" */            if (!header.standardDate.startsWith("199")                    && !header.standardDate.startsWith("20")) {                Debug.output("RpfFrame.read: Invalid date in header: "                        + header.standardDate);                return false;            }            // Need to do this right after the header...            binFile.seek(header.locationSectionLocation);            fileSections = new RpfFileSections(binFile);            RpfFileSections.RpfLocationRecord[] loc = fileSections.getLocations(RpfFileSections.FRAME_LOCATION_KEY);            attributes = fileSections.parseAttributes(binFile);            coverage = fileSections.parseCoverageSection(binFile);            colortable = new RpfColortable();            getColors(binFile, colortable);            /* DKS: from index to componentLocation */            if (loc[0] == null) {                Debug.output("RpfFrame: No compression section!");                return false;            }            /* Read the compression tables */            binFile.seek(loc[0].componentLocation);            compression = new Compression(binFile);            if (DEBUG_RPFDETAIL)                Debug.output(compression.toString());            if (loc[2] == null) {                Debug.output("Warning: Can't find compr. lookup subsection in FrameFile:");                Debug.output("   Using alternate computation");                /* length of compr. sect. subhdr = 10 */                binFile.seek(loc[0].componentLocation + 10);            } else {                /*                 * DKS: Position at start of compression lookup table                 * offset record                 */                if (DEBUG_RPFDETAIL) {                    Debug.output("Comp lkup subsect: loc[2].componentLocation(264?): "                            + loc[2].componentLocation);                }                binFile.seek(loc[2].componentLocation);            }            /* 2 new hdr fields */            lookupOffsetTableOffset = (long) binFile.readInteger();            lookupTableOffsetRecLen = (int) binFile.readShort();            if (DEBUG_RPFDETAIL) {                Debug.output("lookupOffsetTableOffset(6): "                        + lookupOffsetTableOffset);                Debug.output("lookupTableOffsetRecLen(14): "                        + lookupTableOffsetRecLen);            }            /* For each compression table */            for (i = 0; i < 4; i++) {                lookupTable[i] = new LookupTable(binFile);                if (DEBUG_RPFDETAIL) {                    Debug.output("Compression lookup table offset record " + i);                    Debug.output(lookupTable[i].toString());                }                if (lookupTable[i].records != 4096                        || lookupTable[i].values != 4                        || lookupTable[i].bitLength != 8) {                    Debug.output("RpfFrame: Bad VQ info in compression record");                    return false;                }            } /* for i */            for (i = 0; i < 4; i++) { /* Read compression lookup table */                /*                 * new position from compression lookup subsection:                 * loc[2]                 */                binFile.seek(loc[2].componentLocation + lookupTable[i].offset);                if (DEBUG_RPFDETAIL) {                    currentPos = binFile.getFilePointer();                    Debug.output("Read compr. lookup table (4x4096) at position: "                            + currentPos);                }                for (j = 0; j < 4096; j++)                    table[i][j] = binFile.readBytes(4, false);            } /*               * for i=1 to 4 (# compression tables, 1 for each pixel               * row)               */            /* seek to LOC_ATTRIB_SUBHEADER, ID=141 */            if ((Dchum) && (chumVersion > 1)) { /*                                                 * Chum selected and                                                 * file version > 1                                                 */                if (loc[6] == null) {                    Debug.output("RpfFrame: Can't find ATTRIBUTE_SUBHEADER section!");                    return false;                }                if (DEBUG_RPFDETAIL)                    Debug.output("ATTRIBUTE SUBHEADER location: "                            + loc[6].componentLocation);                binFile.seek(loc[6].componentLocation);                numAttributeOffsetRecs = (int) binFile.readShort();                if (DEBUG_RPFDETAIL)                    Debug.output("numAttributeOffsetRecs: "                            + numAttributeOffsetRecs);                /* Go to Attrib subsection */                if (loc[7] == null) {                    Debug.output("RpfFrame: Can't find ATTRIBUTE_SECTION in Frame file");                    return false;                }                if (DEBUG_RPFDETAIL)                    Debug.output("ATTRIBUTE SECTION location: "                            + loc[7].componentLocation);                binFile.seek(loc[7].componentLocation);                descCount = 0; /* # descriptor strings so far */                for (i = 0; i < numAttributeOffsetRecs; i++) {                    attributeId = (int) binFile.readShort();                    attributeParamId = binFile.read();                    tempc = binFile.read();                    attributeRecOffset = (long) binFile.readInteger();                    /* # subframes impacted */                    if ((attributeId == 24) && (attributeParamId == 4)) {                        /* save file loc */                        fsave = binFile.getFilePointer();                        /* Go to proper spot in attrib section */                        binFile.seek(loc[7].componentLocation                                + attributeRecOffset);                        /* read # subframes impacted */                        numSubframesChummed = (int) binFile.readShort();                        if (DEBUG_RPFDETAIL) {                            Debug.output("n_attrib_chummedSubframe: "                                    + numSubframesChummed);                        }                        /* Read list of subframes chummed */                        /* Assume these are next in file */                        for (j = 0; j < numSubframesChummed; j++) {                            chummedSubframe = (int) binFile.readShort();                            if (DEBUG_RPFDETAIL) {                                Debug.output("chummedSubframe: "                                        + chummedSubframe);                            }                            /* y,x */                            chummed[chummedSubframe / 6][chummedSubframe % 6] = true;                        } /* for j */                        binFile.seek(fsave); /* restore file pos */                    } /* if 24,4 */                    /* Update date */                    if ((attributeId == 24) && (attributeParamId == 3)) {                        /* save file loc */                        fsave = binFile.getFilePointer();                        /* Go to proper spot in attrib section */                        binFile.seek(loc[7].componentLocation                                + attributeRecOffset);                        /* read date */                        descriptorDates[descCount] = binFile.readFixedLengthString(8);                        if (DEBUG_RPFDETAIL)                            Debug.output("descriptorDate: "                                    + descriptorDates[descCount]);                        binFile.seek(fsave); /* restore file pos */                    } /* if 24,3 */                    /* # chars in descriptor */                    if ((attributeId == 24) && (attributeParamId == 6)) {                        /* save file loc */                        fsave = binFile.getFilePointer();                        /* Go to proper spot in attrib section */                        binFile.seek(loc[7].componentLocation                                + attributeRecOffset);                        /* read # chars in descriptor */                        numCharsInDesc = (int) binFile.readShort();                        if (DEBUG_RPFDETAIL) {                            Debug.output("Prepare to fread descriptors[descCount]");                            Debug.output("RpfFrame.read: descCount: "                                    + descCount);                        }                        descriptors[descCount] = binFile.readFixedLengthString(numCharsInDesc);                        /* Array of strings, not 2-d array !!!!???? */                        if (DEBUG_RPFDETAIL) {                            Debug.output("descriptors[descCount]: "                                    + descriptors[descCount]);                        }                        descCount++; /* string number */                        binFile.seek(fsave); /* restore file pos */                    } /* if 24,6 */                } /* for i */            } /* if Dchum */            /* READ THE IMAGE DATA */            if (DEBUG_RPFDETAIL) {                Debug.output("Image descr. subheader location: loc[1].componentLocation(68576?): "                        + loc[1].componentLocation);            }            binFile.seek(loc[1].componentLocation);            image = new Image(binFile);            /* New, DKS. NULL (FF) if no subfr mask table */            subframeMaskTableOffset = binFile.readInteger();            if (DEBUG_RPFDETAIL) {                Debug.output(image.toString());                Debug.output("subframeMaskTableOffset: "                        + subframeMaskTableOffset);            }            if (subframeMaskTableOffset == 0) { /* ERROR Check */                Debug.error("RpfFrame.read(): subframeMaskTableOffset==0.");                return false;            }            if (subframeMaskTableOffset == 0xFFFFFFFF)                allSubframes = true;            else                allSubframes = false;            if (Debug.debugging("rpfframe")) {                Debug.output("allSubframes: " + allSubframes);            }            if (!allSubframes) { /* Read mask data */                /* fseek to LOC_MASK_SUBSECTION, ID=138 */                if (loc[5] == null) {                    Debug.error("RpfFrame.read(): Can't find MASK_SUBSECTION section in Frame file");                    return false;                }                if (DEBUG_RPFDETAIL) {                    Debug.output("MASK SUBSECTION location: "                            + loc[5].componentLocation);                }                binFile.seek(loc[5].componentLocation + subframeMaskTableOffset);                for (i = 0; i < 6; i++) { /* y */                    for (j = 0; j < 6; j++) {                        subframeOffset[i][j] = (long) binFile.readInteger();                        if (subframeOffset[i][j] == 0xFFFFFFFF)                            masked[i][j] = true; /* subfr masked */                        if (DEBUG_RPFDETAIL) {                            Debug.output("i:" + i + ", j:" + j                                    + ", masked[i][j]: " + masked[i][j]);                        }                    } /* for j */                } /* for i */            } /* if !allSubframes */            if (image.vertSubframes != 6 || image.horizSubframes != 6) {                Debug.output("Not 6x6 subframes per frame: must be masked.");            }            rowBytes = 256 / 4 * 3 / 2;            // Is this section needed??            /* fseek to LOC_IMAGE_DISPLAY_PARAM_SUBHEADER, ID=137 */            if (loc[4] == null) {                Debug.error("RpfFrame.read(): Can't find IMAGE_DISPLAY_PARAM_SUBHEADER section!");                return false;            }            /* Image Display Parameters Subheader */            if (DEBUG_RPFDETAIL) {                Debug.output("IMAGE Display params subheader location: "                        + loc[4].componentLocation);            }            binFile.seek(loc[4].componentLocation);            /* Go to start of image spatial data subsection */            if (loc[3] == null) {                Debug.output("WARNING: Can't find Image spatial data subsection in FrameFile:");                Debug.output("   Using alternate computation");                /*                 * DKS. skip 14 bytes of image display parameters                 * subheader instead                 */                binFile.seek(loc[4].componentLocation + 14);            } else {                /*                 * DKS: Position at start of image spatial data                 * subsection                 */                currentPos = binFile.getFilePointer();                if (DEBUG_RPFDETAIL) {                    Debug.output("Current frame file position(68595?): "                            + currentPos);                    Debug.output("Image spatial data subsect: loc[3](68609?): "                            + loc[3].componentLocation);                }                binFile.seek(loc[3].componentLocation);            } /* else */            /* Read subframes from top left, row-wise */            for (i = 0; i < 6; i++) { /* row */                for (j = 0; j < 6; j++) { /* col */                    /* DKS. New: init indices to valid subframes */                    indices[i][j] = i * 6 + j;                    /* (256/4)=64. 64*64 * 12bits / 8bits = 6144 bytes */                    if (!masked[i][j]) {                        compressedSubframe[i][j] = binFile.readBytes(6144,                                false);                        if (DEBUG_RPFDETAIL)                            Debug.output(" i:" + i + ", j:" + j                                    + ", read image data. rc(6144):"                                    + compressedSubframe[i][j].length);                    } else                        compressedSubframe[i][j] = new byte[6144];                }            }                    } catch (IOException e) {            Debug.error("RpfFrame: read(): File IO Error!\n" + e);            return false;        } catch (FormatException f) {            Debug.error("RpfFrame: read(): File IO Format error!" + f);            return false;        }        if (DEBUG_RPFDETAIL) {            Debug.output("LEAVE RPFFRAME.READ");        }        valid = true;        return valid;    } /* read */