source: josm/trunk/src/com/drew/imaging/jpeg/JpegSegmentData.java@ 6127

Last change on this file since 6127 was 6127, checked in by bastiK, 12 years ago

applied #8895 - Upgrade metadata-extractor to v. 2.6.4 (patch by ebourg)

File size: 7.4 KB
RevLine 
[4231]1/*
[6127]2 * Copyright 2002-2012 Drew Noakes
[4231]3 *
[6127]4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
[4231]7 *
[6127]8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * More information about this project is available at:
17 *
18 * http://drewnoakes.com/code/exif/
19 * http://code.google.com/p/metadata-extractor/
[4231]20 */
21package com.drew.imaging.jpeg;
22
[6127]23import com.drew.lang.annotations.NotNull;
24import com.drew.lang.annotations.Nullable;
25
[4231]26import java.io.*;
27import java.util.ArrayList;
28import java.util.HashMap;
29import java.util.List;
30
31/**
32 * Holds a collection of Jpeg data segments. This need not necessarily be all segments
[6127]33 * within the Jpeg. For example, it may be convenient to store only the non-image
[4231]34 * segments when analysing (or serializing) metadata.
[6127]35 * <p/>
36 * Segments are keyed via their segment marker (a byte). Where multiple segments use the
37 * same segment marker, they will all be stored and available.
38 *
39 * @author Drew Noakes http://drewnoakes.com
[4231]40 */
41public class JpegSegmentData implements Serializable
42{
[6127]43 private static final long serialVersionUID = 7110175216435025451L;
[4231]44
45 /** A map of byte[], keyed by the segment marker */
[6127]46 @NotNull
47 private final HashMap<Byte, List<byte[]>> _segmentDataMap = new HashMap<Byte, List<byte[]>>(10);
[4231]48
[6127]49 /**
50 * Adds segment bytes to the collection.
51 * @param segmentMarker
52 * @param segmentBytes
53 */
54 @SuppressWarnings({ "MismatchedQueryAndUpdateOfCollection" })
55 public void addSegment(byte segmentMarker, @NotNull byte[] segmentBytes)
[4231]56 {
[6127]57 final List<byte[]> segmentList = getOrCreateSegmentList(segmentMarker);
[4231]58 segmentList.add(segmentBytes);
59 }
60
[6127]61 /**
62 * Gets the first Jpeg segment data for the specified marker.
63 * @param segmentMarker the byte identifier for the desired segment
64 * @return a byte[] containing segment data or null if no data exists for that segment
65 */
66 @Nullable
[4231]67 public byte[] getSegment(byte segmentMarker)
68 {
69 return getSegment(segmentMarker, 0);
70 }
71
[6127]72 /**
73 * Gets segment data for a specific occurrence and marker. Use this method when more than one occurrence
74 * of segment data for a given marker exists.
75 * @param segmentMarker identifies the required segment
76 * @param occurrence the zero-based index of the occurrence
77 * @return the segment data as a byte[], or null if no segment exists for the marker & occurrence
78 */
79 @Nullable
[4231]80 public byte[] getSegment(byte segmentMarker, int occurrence)
81 {
[6127]82 final List<byte[]> segmentList = getSegmentList(segmentMarker);
[4231]83
84 if (segmentList==null || segmentList.size()<=occurrence)
85 return null;
86 else
[6127]87 return segmentList.get(occurrence);
[4231]88 }
89
[6127]90 /**
91 * Returns all instances of a given Jpeg segment. If no instances exist, an empty sequence is returned.
92 *
93 * @param segmentMarker a number which identifies the type of Jpeg segment being queried
94 * @return zero or more byte arrays, each holding the data of a Jpeg segment
95 */
96 @NotNull
97 public Iterable<byte[]> getSegments(byte segmentMarker)
[4231]98 {
[6127]99 final List<byte[]> segmentList = getSegmentList(segmentMarker);
100 return segmentList==null ? new ArrayList<byte[]>() : segmentList;
[4231]101 }
102
[6127]103 @Nullable
104 public List<byte[]> getSegmentList(byte segmentMarker)
[4231]105 {
[6127]106 return _segmentDataMap.get(Byte.valueOf(segmentMarker));
[4231]107 }
108
[6127]109 @NotNull
110 private List<byte[]> getOrCreateSegmentList(byte segmentMarker)
[4231]111 {
[6127]112 List<byte[]> segmentList;
113 if (_segmentDataMap.containsKey(segmentMarker)) {
114 segmentList = _segmentDataMap.get(segmentMarker);
115 } else {
116 segmentList = new ArrayList<byte[]>();
117 _segmentDataMap.put(segmentMarker, segmentList);
118 }
119 return segmentList;
[4231]120 }
121
[6127]122 /**
123 * Returns the count of segment data byte arrays stored for a given segment marker.
124 * @param segmentMarker identifies the required segment
125 * @return the segment count (zero if no segments exist).
126 */
127 public int getSegmentCount(byte segmentMarker)
[4231]128 {
[6127]129 final List<byte[]> segmentList = getSegmentList(segmentMarker);
130 return segmentList == null ? 0 : segmentList.size();
[4231]131 }
132
[6127]133 /**
134 * Removes a specified instance of a segment's data from the collection. Use this method when more than one
135 * occurrence of segment data for a given marker exists.
136 * @param segmentMarker identifies the required segment
137 * @param occurrence the zero-based index of the segment occurrence to remove.
138 */
139 @SuppressWarnings({ "MismatchedQueryAndUpdateOfCollection" })
140 public void removeSegmentOccurrence(byte segmentMarker, int occurrence)
[4231]141 {
[6127]142 final List<byte[]> segmentList = _segmentDataMap.get(Byte.valueOf(segmentMarker));
143 segmentList.remove(occurrence);
[4231]144 }
145
[6127]146 /**
147 * Removes all segments from the collection having the specified marker.
148 * @param segmentMarker identifies the required segment
149 */
150 public void removeSegment(byte segmentMarker)
151 {
152 _segmentDataMap.remove(Byte.valueOf(segmentMarker));
153 }
154
155 /**
156 * Determines whether data is present for a given segment marker.
157 * @param segmentMarker identifies the required segment
158 * @return true if data exists, otherwise false
159 */
[4231]160 public boolean containsSegment(byte segmentMarker)
161 {
[6127]162 return _segmentDataMap.containsKey(Byte.valueOf(segmentMarker));
[4231]163 }
164
[6127]165 /**
166 * Serialises the contents of a JpegSegmentData to a file.
167 * @param file to file to write from
168 * @param segmentData the data to write
169 * @throws IOException if problems occur while writing
170 */
171 public static void toFile(@NotNull File file, @NotNull JpegSegmentData segmentData) throws IOException
[4231]172 {
[6127]173 FileOutputStream fileOutputStream = null;
[4231]174 try
175 {
[6127]176 fileOutputStream = new FileOutputStream(file);
177 new ObjectOutputStream(fileOutputStream).writeObject(segmentData);
[4231]178 }
179 finally
180 {
[6127]181 if (fileOutputStream!=null)
182 fileOutputStream.close();
[4231]183 }
184 }
185
[6127]186 /**
187 * Deserialises the contents of a JpegSegmentData from a file.
188 * @param file the file to read from
189 * @return the JpegSegmentData as read
190 * @throws IOException if problems occur while reading
191 * @throws ClassNotFoundException if problems occur while deserialising
192 */
193 @NotNull
194 public static JpegSegmentData fromFile(@NotNull File file) throws IOException, ClassNotFoundException
[4231]195 {
196 ObjectInputStream inputStream = null;
197 try
198 {
199 inputStream = new ObjectInputStream(new FileInputStream(file));
200 return (JpegSegmentData)inputStream.readObject();
201 }
202 finally
203 {
204 if (inputStream!=null)
205 inputStream.close();
206 }
207 }
208}
Note: See TracBrowser for help on using the repository browser.