View Javadoc
1   /*
2    *  Licensed under the Apache License, Version 2.0 (the "License");
3    *  you may not use this file except in compliance with the License.
4    *  You may obtain a copy of the License at
5    *
6    *       http://www.apache.org/licenses/LICENSE-2.0
7    *
8    *  Unless required by applicable law or agreed to in writing, software
9    *  distributed under the License is distributed on an "AS IS" BASIS,
10   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11   *  See the License for the specific language governing permissions and
12   *  limitations under the License.
13   *  under the License.
14   */
15  
16  package org.apache.commons.imaging.formats.pcx;
17  
18  import java.io.IOException;
19  import java.io.InputStream;
20  import java.util.Arrays;
21  
22  import org.apache.commons.imaging.ImagingException;
23  import org.apache.commons.imaging.common.BinaryFunctions;
24  
25  final class RleReader {
26      private final boolean isCompressed;
27      private int count;
28      private byte sample;
29  
30      RleReader(final boolean isCompressed) {
31          this.isCompressed = isCompressed;
32      }
33  
34      void read(final InputStream is, final byte[] samples) throws IOException, ImagingException {
35          if (isCompressed) {
36              final int prefill = Math.min(count, samples.length);
37              Arrays.fill(samples, 0, prefill, sample);
38              count -= prefill;
39  
40              for (int bytesRead = prefill; bytesRead < samples.length;) {
41                  final byte b = BinaryFunctions.readByte("RleByte", is, "Error reading image data");
42                  if ((b & 0xc0) == 0xc0) {
43                      count = b & 0x3f;
44                      sample = BinaryFunctions.readByte("RleValue", is, "Error reading image data");
45                  } else {
46                      count = 1;
47                      sample = b;
48                  }
49                  final int samplesToAdd = Math.min(count, samples.length - bytesRead);
50                  Arrays.fill(samples, bytesRead, bytesRead + samplesToAdd, sample);
51                  bytesRead += samplesToAdd;
52                  count -= samplesToAdd;
53              }
54          } else {
55              int r;
56              for (int bytesRead = 0; bytesRead < samples.length; bytesRead += r) {
57                  r = is.read(samples, bytesRead, samples.length - bytesRead);
58                  if (r < 0) {
59                      throw new ImagingException("Premature end of file reading image data");
60                  }
61              }
62          }
63      }
64  }