Changeset 8132 in josm for trunk/src/com/drew/imaging/jpeg/JpegSegmentData.java
- Timestamp:
- 2015-03-10T01:17:39+01:00 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/com/drew/imaging/jpeg/JpegSegmentData.java ¶
r6127 r8132 1 1 /* 2 * Copyright 2002-201 2Drew Noakes2 * Copyright 2002-2015 Drew Noakes 3 3 * 4 4 * Licensed under the Apache License, Version 2.0 (the "License"); … … 16 16 * More information about this project is available at: 17 17 * 18 * http://drewnoakes.com/code/exif/ 19 * http ://code.google.com/p/metadata-extractor/18 * https://drewnoakes.com/code/exif/ 19 * https://github.com/drewnoakes/metadata-extractor 20 20 */ 21 21 package com.drew.imaging.jpeg; … … 24 24 import com.drew.lang.annotations.Nullable; 25 25 26 import java.io.*; 27 import java.util.ArrayList; 28 import java.util.HashMap; 29 import java.util.List; 26 import java.util.*; 30 27 31 28 /** 32 * Holds a collection of Jpeg data segments. This need not necessarily be all segments 33 * within the Jpeg. For example, it may be convenient to store only the non-image 34 * segments when analysing (or serializing) metadata. 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 29 * Holds a collection of JPEG data segments. This need not necessarily be all segments 30 * within the JPEG. For example, it may be convenient to store only the non-image 31 * segments when analysing metadata. 32 * <p> 33 * Segments are keyed via their {@link JpegSegmentType}. Where multiple segments use the 34 * same segment type, they will all be stored and available. 35 * <p> 36 * Each segment type may contain multiple entries. Conceptually the model is: 37 * <code>Map<JpegSegmentType, Collection<byte[]>></code>. This class provides 38 * convenience methods around that structure. 39 * 40 * @author Drew Noakes https://drewnoakes.com 40 41 */ 41 public class JpegSegmentData implements Serializable42 public class JpegSegmentData 42 43 { 43 private static final long serialVersionUID = 7110175216435025451L; 44 45 /** A map of byte[], keyed by the segment marker */ 44 // TODO key this on JpegSegmentType rather than Byte, and hopefully lose much of the use of 'byte' with this class 46 45 @NotNull 47 46 private final HashMap<Byte, List<byte[]>> _segmentDataMap = new HashMap<Byte, List<byte[]>>(10); … … 49 48 /** 50 49 * 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) 56 { 57 final List<byte[]> segmentList = getOrCreateSegmentList(segmentMarker); 58 segmentList.add(segmentBytes); 59 } 60 61 /** 62 * Gets the first Jpeg segment data for the specified marker. 63 * @param segmentMarker the byte identifier for the desired segment 50 * 51 * @param segmentType the type of the segment being added 52 * @param segmentBytes the byte array holding data for the segment being added 53 */ 54 @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) 55 public void addSegment(byte segmentType, @NotNull byte[] segmentBytes) 56 { 57 getOrCreateSegmentList(segmentType).add(segmentBytes); 58 } 59 60 /** 61 * Gets the set of JPEG segment type identifiers. 62 */ 63 public Iterable<JpegSegmentType> getSegmentTypes() 64 { 65 Set<JpegSegmentType> segmentTypes = new HashSet<JpegSegmentType>(); 66 67 for (Byte segmentTypeByte : _segmentDataMap.keySet()) 68 { 69 JpegSegmentType segmentType = JpegSegmentType.fromByte(segmentTypeByte); 70 if (segmentType == null) { 71 throw new IllegalStateException("Should not have a segmentTypeByte that is not in the enum: " + Integer.toHexString(segmentTypeByte)); 72 } 73 segmentTypes.add(segmentType); 74 } 75 76 return segmentTypes; 77 } 78 79 /** 80 * Gets the first JPEG segment data for the specified type. 81 * 82 * @param segmentType the JpegSegmentType for the desired segment 64 83 * @return a byte[] containing segment data or null if no data exists for that segment 65 84 */ 66 85 @Nullable 67 public byte[] getSegment(byte segmentMarker) 68 { 69 return getSegment(segmentMarker, 0); 70 } 71 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 80 public byte[] getSegment(byte segmentMarker, int occurrence) 81 { 82 final List<byte[]> segmentList = getSegmentList(segmentMarker); 83 84 if (segmentList==null || segmentList.size()<=occurrence) 85 return null; 86 else 87 return segmentList.get(occurrence); 88 } 89 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) 98 { 99 final List<byte[]> segmentList = getSegmentList(segmentMarker); 100 return segmentList==null ? new ArrayList<byte[]>() : segmentList; 101 } 102 103 @Nullable 104 public List<byte[]> getSegmentList(byte segmentMarker) 105 { 106 return _segmentDataMap.get(Byte.valueOf(segmentMarker)); 107 } 108 109 @NotNull 110 private List<byte[]> getOrCreateSegmentList(byte segmentMarker) 86 public byte[] getSegment(byte segmentType) 87 { 88 return getSegment(segmentType, 0); 89 } 90 91 /** 92 * Gets the first JPEG segment data for the specified type. 93 * 94 * @param segmentType the JpegSegmentType for the desired segment 95 * @return a byte[] containing segment data or null if no data exists for that segment 96 */ 97 @Nullable 98 public byte[] getSegment(@NotNull JpegSegmentType segmentType) 99 { 100 return getSegment(segmentType.byteValue, 0); 101 } 102 103 /** 104 * Gets segment data for a specific occurrence and type. Use this method when more than one occurrence 105 * of segment data for a given type exists. 106 * 107 * @param segmentType identifies the required segment 108 * @param occurrence the zero-based index of the occurrence 109 * @return the segment data as a byte[], or null if no segment exists for the type & occurrence 110 */ 111 @Nullable 112 public byte[] getSegment(@NotNull JpegSegmentType segmentType, int occurrence) 113 { 114 return getSegment(segmentType.byteValue, occurrence); 115 } 116 117 /** 118 * Gets segment data for a specific occurrence and type. Use this method when more than one occurrence 119 * of segment data for a given type exists. 120 * 121 * @param segmentType identifies the required segment 122 * @param occurrence the zero-based index of the occurrence 123 * @return the segment data as a byte[], or null if no segment exists for the type & occurrence 124 */ 125 @Nullable 126 public byte[] getSegment(byte segmentType, int occurrence) 127 { 128 final List<byte[]> segmentList = getSegmentList(segmentType); 129 130 return segmentList != null && segmentList.size() > occurrence 131 ? segmentList.get(occurrence) 132 : null; 133 } 134 135 /** 136 * Returns all instances of a given JPEG segment. If no instances exist, an empty sequence is returned. 137 * 138 * @param segmentType a number which identifies the type of JPEG segment being queried 139 * @return zero or more byte arrays, each holding the data of a JPEG segment 140 */ 141 @NotNull 142 public Iterable<byte[]> getSegments(@NotNull JpegSegmentType segmentType) 143 { 144 return getSegments(segmentType.byteValue); 145 } 146 147 /** 148 * Returns all instances of a given JPEG segment. If no instances exist, an empty sequence is returned. 149 * 150 * @param segmentType a number which identifies the type of JPEG segment being queried 151 * @return zero or more byte arrays, each holding the data of a JPEG segment 152 */ 153 @NotNull 154 public Iterable<byte[]> getSegments(byte segmentType) 155 { 156 final List<byte[]> segmentList = getSegmentList(segmentType); 157 return segmentList == null ? new ArrayList<byte[]>() : segmentList; 158 } 159 160 @Nullable 161 private List<byte[]> getSegmentList(byte segmentType) 162 { 163 return _segmentDataMap.get(segmentType); 164 } 165 166 @NotNull 167 private List<byte[]> getOrCreateSegmentList(byte segmentType) 111 168 { 112 169 List<byte[]> segmentList; 113 if (_segmentDataMap.containsKey(segment Marker)) {114 segmentList = _segmentDataMap.get(segment Marker);170 if (_segmentDataMap.containsKey(segmentType)) { 171 segmentList = _segmentDataMap.get(segmentType); 115 172 } else { 116 173 segmentList = new ArrayList<byte[]>(); 117 _segmentDataMap.put(segment Marker, segmentList);174 _segmentDataMap.put(segmentType, segmentList); 118 175 } 119 176 return segmentList; … … 121 178 122 179 /** 123 * Returns the count of segment data byte arrays stored for a given segment marker. 124 * @param segmentMarker identifies the required segment 180 * Returns the count of segment data byte arrays stored for a given segment type. 181 * 182 * @param segmentType identifies the required segment 125 183 * @return the segment count (zero if no segments exist). 126 184 */ 127 public int getSegmentCount(byte segmentMarker) 128 { 129 final List<byte[]> segmentList = getSegmentList(segmentMarker); 185 public int getSegmentCount(@NotNull JpegSegmentType segmentType) 186 { 187 return getSegmentCount(segmentType.byteValue); 188 } 189 190 /** 191 * Returns the count of segment data byte arrays stored for a given segment type. 192 * 193 * @param segmentType identifies the required segment 194 * @return the segment count (zero if no segments exist). 195 */ 196 public int getSegmentCount(byte segmentType) 197 { 198 final List<byte[]> segmentList = getSegmentList(segmentType); 130 199 return segmentList == null ? 0 : segmentList.size(); 131 200 } … … 133 202 /** 134 203 * 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) 141 { 142 final List<byte[]> segmentList = _segmentDataMap.get(Byte.valueOf(segmentMarker)); 204 * occurrence of segment data exists for a given type exists. 205 * 206 * @param segmentType identifies the required segment 207 * @param occurrence the zero-based index of the segment occurrence to remove. 208 */ 209 @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) 210 public void removeSegmentOccurrence(@NotNull JpegSegmentType segmentType, int occurrence) 211 { 212 removeSegmentOccurrence(segmentType.byteValue, occurrence); 213 } 214 215 /** 216 * Removes a specified instance of a segment's data from the collection. Use this method when more than one 217 * occurrence of segment data exists for a given type exists. 218 * 219 * @param segmentType identifies the required segment 220 * @param occurrence the zero-based index of the segment occurrence to remove. 221 */ 222 @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) 223 public void removeSegmentOccurrence(byte segmentType, int occurrence) 224 { 225 final List<byte[]> segmentList = _segmentDataMap.get(segmentType); 143 226 segmentList.remove(occurrence); 144 227 } 145 228 146 229 /** 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 230 * Removes all segments from the collection having the specified type. 231 * 232 * @param segmentType identifies the required segment 233 */ 234 public void removeSegment(@NotNull JpegSegmentType segmentType) 235 { 236 removeSegment(segmentType.byteValue); 237 } 238 239 /** 240 * Removes all segments from the collection having the specified type. 241 * 242 * @param segmentType identifies the required segment 243 */ 244 public void removeSegment(byte segmentType) 245 { 246 _segmentDataMap.remove(segmentType); 247 } 248 249 /** 250 * Determines whether data is present for a given segment type. 251 * 252 * @param segmentType identifies the required segment 158 253 * @return true if data exists, otherwise false 159 254 */ 160 public boolean containsSegment(byte segmentMarker) 161 { 162 return _segmentDataMap.containsKey(Byte.valueOf(segmentMarker)); 163 } 164 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 172 { 173 FileOutputStream fileOutputStream = null; 174 try 175 { 176 fileOutputStream = new FileOutputStream(file); 177 new ObjectOutputStream(fileOutputStream).writeObject(segmentData); 178 } 179 finally 180 { 181 if (fileOutputStream!=null) 182 fileOutputStream.close(); 183 } 184 } 185 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 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 } 255 public boolean containsSegment(@NotNull JpegSegmentType segmentType) 256 { 257 return containsSegment(segmentType.byteValue); 258 } 259 260 /** 261 * Determines whether data is present for a given segment type. 262 * 263 * @param segmentType identifies the required segment 264 * @return true if data exists, otherwise false 265 */ 266 public boolean containsSegment(byte segmentType) 267 { 268 return _segmentDataMap.containsKey(segmentType); 207 269 } 208 270 }
Note:
See TracChangeset
for help on using the changeset viewer.
