Coverage Report - org.jaudiotagger.tag.asf.AsfTagCoverField
 
Classes in this File Line Coverage Branch Coverage Complexity
AsfTagCoverField
84%
55/65
68%
15/22
3.111
 
 1  
 package org.jaudiotagger.tag.asf;
 2  
 
 3  
 import org.jaudiotagger.audio.asf.data.AsfHeader;
 4  
 import org.jaudiotagger.audio.asf.data.MetadataDescriptor;
 5  
 import org.jaudiotagger.logging.ErrorMessage;
 6  
 import org.jaudiotagger.tag.id3.valuepair.ImageFormats;
 7  
 import org.jaudiotagger.tag.asf.AbstractAsfTagImageField;
 8  
 import org.jaudiotagger.tag.asf.AsfFieldKey;
 9  
 
 10  
 import java.io.ByteArrayOutputStream;
 11  
 import java.io.UnsupportedEncodingException;
 12  
 import java.util.logging.Logger;
 13  
 
 14  
 /**
 15  
  * Encapsulates the WM/Pictures provides some convenience methods for decoding
 16  
  * the binary data it contains
 17  
  * <p/>
 18  
  * The value of a WM/Pictures metadata descriptor is as follows:
 19  
  * <p/>
 20  
  * byte0 Picture Type byte1-4 Length of the image data mime type encoded as
 21  
  * UTF-16LE null byte null byte description encoded as UTF-16LE (optional) null
 22  
  * byte null byte image data
 23  
  */
 24  
 public class AsfTagCoverField extends AbstractAsfTagImageField
 25  
 {
 26  
     /**
 27  
      * Logger Object
 28  
      */
 29  4
     public final static Logger LOGGER = Logger
 30  
             .getLogger("org.jaudiotagger.audio.asf.tag");
 31  
 
 32  
     /**
 33  
      * Description
 34  
      */
 35  
     private String description;
 36  
 
 37  
     /**
 38  
      * We need this to retrieve the buffered image, if required
 39  
      */
 40  94
     private int endOfName = 0;
 41  
 
 42  
     /**
 43  
      * Image Data Size as read
 44  
      */
 45  
     private int imageDataSize;
 46  
 
 47  
     /**
 48  
      * Mimetype of binary
 49  
      */
 50  
     private String mimeType;
 51  
 
 52  
     /**
 53  
      * Picture Type
 54  
      */
 55  
     private int pictureType;
 56  
 
 57  
     /**
 58  
      * Create New Image Field
 59  
      * 
 60  
      * @param imageData
 61  
      * @param pictureType
 62  
      * @param description
 63  
      * @param mimeType
 64  
      */
 65  
     public AsfTagCoverField(final byte[] imageData, final int pictureType,
 66  
             final String description, final String mimeType) {
 67  12
         super(new MetadataDescriptor(AsfFieldKey.COVER_ART.getFieldName(),
 68  
                 MetadataDescriptor.TYPE_BINARY));
 69  12
         this.getDescriptor()
 70  
                 .setBinaryValue(
 71  
                         createRawContent(imageData, pictureType, description,
 72  
                                 mimeType));
 73  12
     }
 74  
 
 75  
     /**
 76  
      * Creates an instance from a metadata descriptor
 77  
      * 
 78  
      * @param source
 79  
      *            The metadata descriptor, whose content is published.<br>
 80  
      */
 81  
     public AsfTagCoverField(final MetadataDescriptor source) {
 82  82
         super(source);
 83  
 
 84  82
         if (!source.getName().equals(AsfFieldKey.COVER_ART.getFieldName())) {
 85  0
             throw new IllegalArgumentException(
 86  
                     "Descriptor description must be WM/Picture");
 87  
         }
 88  82
         if (source.getType() != MetadataDescriptor.TYPE_BINARY) {
 89  0
             throw new IllegalArgumentException("Descriptor type must be binary");
 90  
         }
 91  
 
 92  
         try {
 93  82
             processRawContent();
 94  0
         } catch (final UnsupportedEncodingException uee) {
 95  
             // Should never happen
 96  0
             throw new RuntimeException(uee); // NOPMD by Christian Laireiter on 5/9/09 5:45 PM
 97  82
         }
 98  82
     }
 99  
 
 100  
     private byte[] createRawContent(final byte[] data, final int pictureType,
 101  
             final String description, String mimeType) { // NOPMD by Christian Laireiter on 5/9/09 5:46 PM
 102  12
         this.description = description;
 103  
 
 104  
         // Get Mimetype from data if not already setField
 105  12
         if (mimeType == null) {
 106  4
             mimeType = ImageFormats.getMimeTypeForBinarySignature(data);
 107  
             // Couldnt identify lets default to png because probably error in
 108  
             // code because not 100% sure how to identify
 109  
             // formats
 110  4
             if (mimeType == null) {
 111  0
                 LOGGER.warning(ErrorMessage.GENERAL_UNIDENITIFED_IMAGE_FORMAT
 112  
                         .getMsg());
 113  0
                 mimeType = ImageFormats.MIME_TYPE_PNG;
 114  
             }
 115  
         }
 116  
 
 117  12
         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
 118  
 
 119  
         // PictureType
 120  12
         baos.write(pictureType);
 121  
 
 122  
         // ImageDataSize
 123  12
         baos.write(org.jaudiotagger.audio.generic.Utils
 124  
                 .getSizeLEInt32(data.length), 0, 4);
 125  
 
 126  
         // mimetype
 127  
         byte[] mimeTypeData;
 128  
         try {
 129  12
             mimeTypeData = mimeType.getBytes(AsfHeader.ASF_CHARSET.name());
 130  0
         } catch (final UnsupportedEncodingException uee) {
 131  
             // Should never happen
 132  0
             throw new RuntimeException("Unable to find encoding:" // NOPMD by Christian Laireiter on 5/9/09 5:45 PM
 133  
                     + AsfHeader.ASF_CHARSET.name());
 134  12
         }
 135  12
         baos.write(mimeTypeData, 0, mimeTypeData.length);
 136  
 
 137  
         // Seperator
 138  12
         baos.write(0x00);
 139  12
         baos.write(0x00);
 140  
 
 141  
         // description
 142  12
         if (description != null && description.length() > 0) {
 143  
             byte[] descriptionData;
 144  
             try {
 145  4
                 descriptionData = description.getBytes(AsfHeader.ASF_CHARSET
 146  
                         .name());
 147  0
             } catch (final UnsupportedEncodingException uee) {
 148  
                 // Should never happen
 149  0
                 throw new RuntimeException("Unable to find encoding:" // NOPMD by Christian Laireiter on 5/9/09 5:45 PM
 150  
                         + AsfHeader.ASF_CHARSET.name());
 151  4
             }
 152  4
             baos.write(descriptionData, 0, descriptionData.length);
 153  
         }
 154  
 
 155  
         // Seperator (always write whther or not we have descriptor field)
 156  12
         baos.write(0x00);
 157  12
         baos.write(0x00);
 158  
 
 159  
         // Image data
 160  12
         baos.write(data, 0, data.length);
 161  
 
 162  12
         return baos.toByteArray();
 163  
     }
 164  
 
 165  
     public String getDescription() {
 166  40
         return this.description;
 167  
     }
 168  
 
 169  
     @Override
 170  
     public int getImageDataSize() {
 171  12
         return this.imageDataSize;
 172  
     }
 173  
 
 174  
     public String getMimeType() {
 175  40
         return this.mimeType;
 176  
     }
 177  
 
 178  
     public int getPictureType() {
 179  44
         return this.pictureType;
 180  
     }
 181  
 
 182  
     /**
 183  
      * @return the raw image data only
 184  
      */
 185  
     @Override
 186  
     public byte[] getRawImageData() {
 187  100
         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
 188  100
         baos.write(getRawContent(), this.endOfName, this.toWrap
 189  
                 .getRawDataSize()
 190  
                 - this.endOfName);
 191  100
         return baos.toByteArray();
 192  
     }
 193  
 
 194  
     private void processRawContent() throws UnsupportedEncodingException {
 195  
         // PictureType
 196  82
         this.pictureType = this.getRawContent()[0];
 197  
 
 198  
         // ImageDataSize
 199  82
         this.imageDataSize = org.jaudiotagger.audio.generic.Utils.getIntLE(this
 200  
                 .getRawContent(), 1, 2);
 201  
 
 202  
         // Set Count to after picture type,datasize and two byte nulls
 203  82
         int count = 5;
 204  82
         this.mimeType = null;
 205  82
         this.description = null; // Optional
 206  82
         int endOfMimeType = 0;
 207  
 
 208  1508
         while (count < this.getRawContent().length - 1) {
 209  1508
             if (getRawContent()[count] == 0 && getRawContent()[count + 1] == 0) {
 210  164
                 if (this.mimeType == null) {
 211  82
                     this.mimeType = new String(getRawContent(), 5, (count) - 5,
 212  
                             "UTF-16LE");
 213  82
                     endOfMimeType = count + 2;
 214  82
                 } else if (this.description == null) {
 215  82
                     this.description = new String(getRawContent(),
 216  
                             endOfMimeType, count - endOfMimeType, "UTF-16LE");
 217  82
                     this.endOfName = count + 2;
 218  82
                     break;
 219  
                 }
 220  
             }
 221  1426
             count += 2; // keep on two byte word boundary
 222  
         }
 223  82
     }
 224  
 
 225  
 }