1 package ubc.midp.mobilephoto.core.util; 
  2  
  3 import java.io.IOException; 
  4 import java.io.InputStream; 
  5  
  6 import lancs.midp.mobilephoto.lib.exceptions.ImagePathNotValidException; 
  7 import lancs.midp.mobilephoto.lib.exceptions.InvalidArrayFormatException; 
  8 import lancs.midp.mobilephoto.lib.exceptions.InvalidImageDataException; 
  9 import lancs.midp.mobilephoto.lib.exceptions.InvalidImageFormatException; 
 10  
 11 import ubc.midp.mobilephoto.core.ui.datamodel.ImageData; 
 12  
 13 /** 
 14  * @author trevor This is a utility class. It performs conversions between Image 
 15  *         objects and byte arrays, and Image metadata objects and byte arrays. 
 16  *         Byte arrays are the main format for storing data in RMS, and for 
 17  *         sending data over the wire. 
 18  */ 
 19 public class ImageUtil { 
 20  
 21   // Delimiter used in record store data to separate fields in a string. 
 22   private static final String DELIMITER = "*"; 
 23  
 24   /** 
 25    * Constructor 
 26    */ 
 27   public ImageUtil() { 
 28     super(); 
 29   } 
 30  
 31   /** 
 32    * This method reads an Image from an Input Stream and converts it from a 
 33    * standard image file format into a byte array, so that it can be 
 34    * transported over wireless protocols such as SMS 
 35    *  
 36    * @throws ImagePathNotValidException 
 37    * @throws InvalidImageFormatException 
 38    */ 
 39   public byte[] readImageAsByteArray(String imageFile) 
 40       throws ImagePathNotValidException, InvalidImageFormatException { 
 41  
 42     byte bArray[] = new byte[1000]; 
 43  
 44     // Read an Image into a byte array 
 45     // Required to transfer images over SMS 
 46     InputStream is = null; 
 47     try { 
 48       is = (InputStream) this.getClass().getResourceAsStream(imageFile); 
 49     } catch (Exception e) { 
 50       throw new ImagePathNotValidException( 
 51           "Path not valid for this image:"+imageFile); 
 52     } 
 53  
 54     int i, len = 0; 
 55     byte bArray2[]; 
 56     byte b[] = new byte[1]; 
 57     try { 
 58       while (is.read(b) != -1) { 
 59  
 60         if (len + 1 >= bArray.length) { 
 61  
 62           bArray2 = new byte[bArray.length]; 
 63  
 64           // Transfer all data from old array to temp array 
 65           for (i = 0; i < len; i++) 
 66             bArray2[i] = bArray[i]; 
 67  
 68           bArray = new byte[bArray2.length + 500]; 
 69  
 70           // Re-Copy contents back into new bigger array 
 71           for (i = 0; i < len; i++) 
 72             bArray[i] = bArray2[i]; 
 73         } 
 74  
 75         // Set the size to be exact 
 76         bArray[len] = b[0]; 
 77         len++; 
 78       } 
 79  
 80       is.close(); 
 81     } catch (IOException e1) { 
 82       throw new InvalidImageFormatException( 
 83           "The file "+imageFile+" does not have PNG format"); 
 84     } catch(NullPointerException e2){ 
 85       throw new ImagePathNotValidException( 
 86           "Path not valid for this image:"+imageFile); 
 87     } 
 88  
 89     return bArray; 
 90   } 
 91  
 92   /** 
 93    *  
 94    * Convert the byte array from a retrieved RecordStore record into the 
 95    * ImageInfo ((renamed ImageData) object Order of the string will look like 
 96    * this: <recordId>*<foreignRecordId>*<labelName>*<imageLabel> Depending 
 97    * on the optional features, additional fields may be: <phoneNum> 
 98    *  
 99    * @throws InvalidArrayFormatException 
100    */ 
101   public ImageData getImageInfoFromBytes(byte[] bytes) 
102       throws InvalidArrayFormatException { 
103  
104     try { 
105       String iiString = new String(bytes); 
106  
107       // Track our position in the String using delimiters 
108       // Ie. Get chars from beginning of String to first Delim 
109       int startIndex = 0; 
110       int endIndex = iiString.indexOf(DELIMITER); 
111  
112       // Get recordID int value as String - everything before first 
113       // delimeter 
114       String intString = iiString.substring(startIndex, endIndex); 
115  
116       // Get 'foreign' record ID corresponding to the image table 
117       startIndex = endIndex + 1; 
118       endIndex = iiString.indexOf(DELIMITER, startIndex); 
119       String fidString = iiString.substring(startIndex, endIndex); 
120  
121       // Get Album name (recordstore) - next delimeter 
122       startIndex = endIndex + 1; 
123       endIndex = iiString.indexOf(DELIMITER, startIndex); 
124       String albumLabel = iiString.substring(startIndex, endIndex); 
125  
126       startIndex = endIndex + 1; 
127       endIndex = iiString.indexOf(DELIMITER, startIndex); 
128        
129       if (endIndex == -1) 
130         endIndex = iiString.length(); 
131        
132       String imageLabel = ""; 
133       imageLabel = iiString.substring(startIndex, endIndex); 
134  
135       // #ifdef includeFavourites 
136       // [EF] Favorite (Scenario 03) 
137       boolean favorite = false; 
138       startIndex = endIndex + 1; 
139       endIndex = iiString.indexOf(DELIMITER, startIndex); 
140        
141       if (endIndex == -1) 
142         endIndex = iiString.length(); 
143        
144       favorite = (iiString.substring(startIndex, endIndex)).equalsIgnoreCase("true"); 
145       // #endif 
146  
147       // #ifdef includeCountViews 
148       // [EF] Number of Views (Scenario 02) 
149       startIndex = endIndex + 1; 
150       endIndex = iiString.indexOf(DELIMITER, startIndex); 
151        
152       if (endIndex == -1) 
153         endIndex = iiString.length(); 
154        
155       int numberOfViews = 0; 
156       try { 
157         numberOfViews = Integer.parseInt(iiString.substring(startIndex, endIndex)); 
158       } catch (RuntimeException e) { 
159         numberOfViews = 0; 
160         e.printStackTrace(); 
161       } 
162       // #endif 
163  
164       // TODO: Add preprocessor statements here 
165  
166       // Get the phone number if one exists 
167 //      if ((endIndex + 1) < iiString.length()) { 
168 //        System.out.println("<* ImageUtil.getImageInfoFromBytes() *> phoneNum : "+endIndex+" < "+iiString.length()); 
169 //        startIndex = endIndex + 1; 
170 //        endIndex = iiString.indexOf(DELIMITER, startIndex); 
171 //        if (endIndex == -1) 
172 //          endIndex = iiString.length(); 
173 //        iiString.substring(startIndex, endIndex); 
174 //      } 
175  
176       Integer x = Integer.valueOf(fidString); 
177       ImageData ii = new ImageData(x.intValue(), albumLabel, imageLabel); 
178        
179       // #ifdef includeFavourites 
180       ii.setFavorite(favorite); 
181       // #endif 
182        
183       // #ifdef includeCountViews 
184       ii.setNumberOfViews(numberOfViews); 
185       // #endif 
186        
187       x = Integer.valueOf(intString); 
188       ii.setRecordId(x.intValue()); 
189       return ii; 
190     } catch (Exception e) { 
191       throw new InvalidArrayFormatException(); 
192     } 
193   } 
194  
195   /** 
196    *  
197    * Convert the ImageInfo (renamed ImageData) object into bytes so we can 
198    * store it in RMS Order of the string will look like this: <recordId>*<foreignRecordId>*<labelName>*<imageLabel> 
199    * Depending on the optional features, additional fields may be: <phoneNum> 
200    * @throws InvalidImageDataException  
201    */ 
202   public byte[] getBytesFromImageInfo(ImageData ii) throws InvalidImageDataException { 
203  
204     // Take each String and get the bytes from it, separating fields with a 
205     // delimiter 
206     try { 
207       String byteString = new String(); 
208  
209       // Convert the record ID for this record 
210       int i = ii.getRecordId(); 
211       Integer j = new Integer(i); 
212       byteString = byteString.concat(j.toString()); 
213       byteString = byteString.concat(DELIMITER); 
214  
215       // Convert the 'Foreign' Record ID field for the corresponding Image 
216       // record store 
217       int i2 = ii.getForeignRecordId(); 
218       Integer j2 = new Integer(i2); 
219       byteString = byteString.concat(j2.toString()); 
220       byteString = byteString.concat(DELIMITER); 
221  
222       // Convert the album name field 
223       byteString = byteString.concat(ii.getParentAlbumName()); 
224       byteString = byteString.concat(DELIMITER); 
225  
226       // Convert the label (name) field 
227       byteString = byteString.concat(ii.getImageLabel()); 
228  
229       // #ifdef includeFavourites 
230       byteString = byteString.concat(DELIMITER); 
231       if (ii.isFavorite()) byteString = byteString.concat("true"); 
232       else byteString = byteString.concat("false"); 
233       // #endif 
234  
235       // #ifdef includeCountViews 
236       byteString = byteString.concat(DELIMITER); 
237       byteString = byteString.concat(""+ii.getNumberOfViews()); 
238       // #endif 
239        
240       // TODO: Add pre-processor statements 
241       // Convert the phone number field 
242       return byteString.getBytes(); 
243     } catch (Exception e) { 
244       throw new InvalidImageDataException("The provided data are not valid"); 
245     } 
246  
247   } 
248  
249 }    
    |