Id3Decoder implements MetadataDecoder { private static ApicFrame decodeApicFrame(ParsableByteArray id3Data, int frameSize, int majorVersion) throws UnsupportedEncodingException { int encoding = id3Data.readUnsignedByte(); String charset = getCharsetName(encoding); byte[] data = new byte[frameSize - 1]; id3Data.readBytes(data, 0, frameSize - 1); String mimeType; int mimeTypeEndIndex; if (majorVersion == 2) { mimeTypeEndIndex = 2; mimeType = "image/" + Util.toLowerInvariant(new String(data, 0, 3, "ISO-8859-1")); if ("image/jpg".equals(mimeType)) { mimeType = "image/jpeg"; } } else { mimeTypeEndIndex = indexOfZeroByte(data, 0); mimeType = Util.toLowerInvariant(new String(data, 0, mimeTypeEndIndex, "ISO-8859-1")); if (mimeType.indexOf('/') == -1) { mimeType = "image/" + mimeType; } } int pictureType = data[mimeTypeEndIndex + 1] & 0xFF; int descriptionStartIndex = mimeTypeEndIndex + 2; int descriptionEndIndex = indexOfEos(data, descriptionStartIndex, encoding); String description = new String(data, descriptionStartIndex, descriptionEndIndex - descriptionStartIndex, charset); int pictureDataStartIndex = descriptionEndIndex + delimiterLength(encoding); byte[] pictureData = copyOfRangeIfValid(data, pictureDataStartIndex, data.length); return new ApicFrame(mimeType, description, pictureType, pictureData); } Id3Decoder();  Id3Decoder(@Nullable FramePredicate framePredicate); @SuppressWarnings("ByteBufferBackingArray") @Override @Nullable Metadata decode(MetadataInputBuffer inputBuffer); @Nullable Metadata decode(byte[] data, int size); static final FramePredicate NO_FRAMES_PREDICATE; static final int ID3_TAG; static final int ID3_HEADER_LENGTH; }
@Test public void testDecodeApicFrame() { byte[] rawId3 = buildSingleFrameTag("APIC", new byte[] {3, 105, 109, 97, 103, 101, 47, 106, 112, 101, 103, 0, 16, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0}); Id3Decoder decoder = new Id3Decoder(); Metadata metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(1); ApicFrame apicFrame = (ApicFrame) metadata.get(0); assertThat(apicFrame.mimeType).isEqualTo("image/jpeg"); assertThat(apicFrame.pictureType).isEqualTo(16); assertThat(apicFrame.description).isEqualTo("Hello World"); assertThat(apicFrame.pictureData).hasLength(10); assertThat(apicFrame.pictureData).isEqualTo(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}); }