Commits

shuerhaaken  committed 6452f95

extend api

  • Participants
  • Parent commits 05aac31

Comments (0)

Files changed (30)

+commit 05aac316b20a57f63cba7c9e1c9ad11b720c3edc
+Author: Jörn Magens <shuerhaaken@googlemail.com>
+Date:   Mon Jul 8 16:30:56 2013 +0200
+
+    api adaption for ogg
+
 commit e2f3904671a4c40870850a2c65b2a85180cb920e
 Author: Jörn Magens <shuerhaaken@googlemail.com>
 Date:   Tue Jul 2 15:30:52 2013 +0200

File libtaginfo/ape_common.cc

 }
 
 
-bool get_ape_item_image(const TagLib::APE::Item &item, char*& data, int &data_length, ImageFileType &image_file_type) {
-    image_file_type = IMAGE_FILE_TYPE_UNKNOWN;
+void get_ape_item_image(const TagLib::APE::Item &item, Image *& image) {
+    image->image_file_type = IMAGE_FILE_TYPE_UNKNOWN;
     if(item.type() == TagLib::APE::Item::Binary) {
         TagLib::ByteVector CoverData = item.binaryData();
         if(CoverData.size() > 0) {
-            data_length = CoverData.size();
-            data = new char[data_length];
-            memcpy(data, CoverData.data(), CoverData.size());
-            return true;
+            image->data_length = CoverData.size();
+            image->data = new char[image->data_length];
+            memcpy(image->data, CoverData.data(), CoverData.size());
+            return;
         }
     }
-    return false;
+    image->data = NULL;
+    image->data_length = 0;
 }
 
 
-bool get_ape_image(TagLib::APE::Tag * apetag, char*& data, int &data_length, ImageFileType &image_file_type) {
-    data = NULL;
-    data_length = 0;
-    
+List<Image *> get_ape_images(TagLib::APE::Tag * apetag) {
+    List<Image *> images;
     if(apetag) {
-        //for(APE::ItemListMap::ConstIterator it = apetag->itemListMap().begin();
-        //   it != apetag->itemListMap().end(); ++it) {
-        //  cout << (*it).first << " - \""  << "\"" << endl; //<< (*it).second.toString()
-        //}
-        
+        Image * image = NULL;
         if(apetag->itemListMap().contains(COVER_ART_FRONT)) {
-            return get_ape_item_image(apetag->itemListMap()[COVER_ART_FRONT],
-                                      data, data_length, image_file_type);
+            image = new Image();
+            get_ape_item_image(apetag->itemListMap()[COVER_ART_FRONT], image);
+            if(image->data && image->data_length > 0)
+                images.prepend(image);
         }
         else if(apetag->itemListMap().contains(COVER_ART_OTHER)) {
-            return get_ape_item_image(apetag->itemListMap()[COVER_ART_OTHER],
-                                      data, data_length, image_file_type);
+            image = new Image();
+            get_ape_item_image(apetag->itemListMap()[COVER_ART_OTHER], image);
+            image->image_type = IMAGE_TYPE_OTHER;
+            if(image->data && image->data_length > 0)
+                images.prepend(image);
         }
-        return false;
     }
-    return false;
+    return images;
 }
 
 
-
-bool set_ape_image(TagLib::APE::Tag * apetag, const char* data, int data_length, ImageFileType image_file_type) {
+//bool get_ape_image(TagLib::APE::Tag * apetag, char*& data, int &data_length, ImageFileType &image_file_type) {
+//    data = NULL;
+//    data_length = 0;
+//    
+//    if(apetag) {
+//        //for(APE::ItemListMap::ConstIterator it = apetag->itemListMap().begin();
+//        //   it != apetag->itemListMap().end(); ++it) {
+//        //  cout << (*it).first << " - \""  << "\"" << endl; //<< (*it).second.toString()
+//        //}
+//        
+//        if(apetag->itemListMap().contains(COVER_ART_FRONT)) {
+//            return get_ape_item_image(apetag->itemListMap()[COVER_ART_FRONT],
+//                                      data, data_length, image_file_type);
+//        }
+//        else if(apetag->itemListMap().contains(COVER_ART_OTHER)) {
+//            return get_ape_item_image(apetag->itemListMap()[COVER_ART_OTHER],
+//                                      data, data_length, image_file_type);
+//        }
+//        return false;
+//    }
+//    return false;
+//}
+
+
+
+void set_ape_images(TagLib::APE::Tag * apetag, const Image ** images, const int image_count) {
     if(apetag) {
         APE::ItemListMap listmap = apetag->itemListMap();
         if(listmap.contains(COVER_ART_FRONT))
             apetag->removeItem(COVER_ART_FRONT);
+        if(listmap.contains(COVER_ART_OTHER))
+            apetag->removeItem(COVER_ART_OTHER);
         
-        if(!data || data_length <= 0)
-            return true;
-        
-        ByteVector ImgData = ByteVector((TagLib::uint) data_length);
-        memcpy(ImgData.data(), data, data_length);
-        
-        APE::Item imageItem = APE::Item();
-        imageItem.setType(TagLib::APE::Item::Binary);
-        imageItem.setKey(COVER_ART_FRONT);
-        imageItem.setBinaryData(ImgData);
-        //if(imageItem.isEmpty())
-        //    cout << "set#5.1" << endl;
-        //else
-        //    cout << "set#5.2" << endl;
-        apetag->setItem(COVER_ART_FRONT, imageItem);
-        return true;
+        for(int p = 0; p < image_count; p++) {
+            if(!images[p]->data || images[p]->data_length == 0)
+                continue;
+            
+            ByteVector ImgData = ByteVector((TagLib::uint) images[p]->data_length);
+            memcpy(ImgData.data(), images[p]->data, images[p]->data_length);
+            
+            APE::Item imageItem = APE::Item();
+            imageItem.setType(TagLib::APE::Item::Binary);
+            if(images[p]->image_type == IMAGE_TYPE_COVER_FRONT)
+                imageItem.setKey(COVER_ART_FRONT);
+            else
+                imageItem.setKey(COVER_ART_OTHER);
+            imageItem.setBinaryData(ImgData);
+            //if(imageItem.isEmpty())
+            //    cout << "set#5.1" << endl;
+            //else
+            //    cout << "set#5.2" << endl;
+            if(images[p]->image_type == IMAGE_TYPE_COVER_FRONT)
+                apetag->setItem(COVER_ART_FRONT, imageItem);
+            else
+                apetag->setItem(COVER_ART_OTHER, imageItem);
+        }
     }
-    return false;
 }
 
 
+//bool set_ape_image(TagLib::APE::Tag * apetag, const char* data, int data_length, ImageFileType image_file_type) {
+//    if(apetag) {
+//        APE::ItemListMap listmap = apetag->itemListMap();
+//        if(listmap.contains(COVER_ART_FRONT))
+//            apetag->removeItem(COVER_ART_FRONT);
+//        
+//        if(!data || data_length <= 0)
+//            return true;
+//        
+//        ByteVector ImgData = ByteVector((TagLib::uint) data_length);
+//        memcpy(ImgData.data(), data, data_length);
+//        
+//        APE::Item imageItem = APE::Item();
+//        imageItem.setType(TagLib::APE::Item::Binary);
+//        imageItem.setKey(COVER_ART_FRONT);
+//        imageItem.setBinaryData(ImgData);
+//        //if(imageItem.isEmpty())
+//        //    cout << "set#5.1" << endl;
+//        //else
+//        //    cout << "set#5.2" << endl;
+//        apetag->setItem(COVER_ART_FRONT, imageItem);
+//        return true;
+//    }
+//    return false;
+//}
+
+
 
 String get_ape_lyrics(APE::Tag * apetag) {
     if(apetag) {

File libtaginfo/apeinfo.cc

 
 
 Image ** ApeInfo::get_images(int &image_count) const {
+    if(taglib_apetag && !taglib_apetag->isEmpty()) {
+        image_count = 0;
+        List<Image *> imagelist = get_ape_images(taglib_apetag);
+        int cnt = imagelist.size();
+        if(cnt > 0) {
+            Image** images = new Image*[cnt];
+            for(List<Image *>::Iterator it = imagelist.begin(); it != imagelist.end(); ++it) {
+                images[image_count] = (*it);
+                image_count++;
+            }
+            return images;
+        }
+    }
     return NULL;
 }
 
 void ApeInfo::set_images(const Image ** images, const int image_count) {
+    if(taglib_apetag)
+        set_ape_images(taglib_apetag, images, image_count);
     return;
 }
 
-//bool ApeInfo::can_handle_images(void) const {
-//    return true;
-//}
-
-//bool ApeInfo::get_image(char*& data, int &data_length, ImageFileType &image_file_type) const {
-//    if(taglib_apetag && !taglib_apetag->isEmpty()) {
-//        return get_ape_image(taglib_apetag, data, data_length, image_file_type);
-//    }
-//    return false;
-//}
-
-//bool ApeInfo::set_image(const char* data, int data_length, ImageFileType image_file_type) {
-//    return taglib_apetag && set_ape_image(taglib_apetag, data, data_length, image_file_type);
-//}
-
 
 
 

File libtaginfo/asfinfo.cc

 #include "tbytevector.h"
 
 #define COMPILATION_FLAG         "WM/PartOfACompilation"
+#define PICTURE_FLAG             "WM/Picture"
 
 
 using namespace TagInfo;
 
 
 
-bool get_asf_image(ASF::Tag * asftag, char*& data, int &data_length, ImageFileType &image_file_type) {
-    data = NULL;
-    data_length = 0;
-    image_file_type = IMAGE_FILE_TYPE_UNKNOWN;
+List<Image *> get_asf_images(ASF::Tag * asftag) {
+    List<Image *> images;
+
     if(asftag) {
-        if(asftag->attributeListMap().contains("WM/Picture")) {
-            ASF::Attribute attr = asftag->attributeListMap()["WM/Picture"].front();
+        if(asftag->attributeListMap().contains(PICTURE_FLAG)) {
+            ASF::Attribute attr = asftag->attributeListMap()[PICTURE_FLAG].front(); 
+            // TODO more pictures
             ASF::Picture pict = attr.toPicture();
-            if(!pict.isValid())
-                return false;
+            //if(!pict.isValid())
+            //    return false;
             
             ByteVector PictureData = pict.picture();
-            
+            Image * image = new Image();
             if(PictureData.size() > 0) {
-                data_length = PictureData.size();
-                data = new char[data_length];
-                memcpy(data, PictureData.data(), PictureData.size());
+                image->data_length = PictureData.size();
+                image->data = new char[image->data_length];
+                memcpy(image->data, PictureData.data(), PictureData.size());
                 
                 String mimetype = pict.mimeType();
                 if(mimetype.find("/jpeg") != -1 || mimetype.find("/jpg") != -1)
-                    image_file_type = IMAGE_FILE_TYPE_JPEG;
+                    image->image_file_type = IMAGE_FILE_TYPE_JPEG;
                 else if(mimetype.find("/png") != -1)
-                    image_file_type = IMAGE_FILE_TYPE_PNG;
+                    image->image_file_type = IMAGE_FILE_TYPE_PNG;
                 
-                return true;
+                image->image_type = IMAGE_TYPE_COVER_FRONT;
+                
+                if(image->data && image->data_length > 0)
+                    images.prepend(image);
             }
         }
     }
-    return false;
+    return images;
 }
 
-bool set_asf_image(ASF::Tag * asftag, const char* data, int data_length, ImageFileType image_file_type) {
+//bool get_asf_image(ASF::Tag * asftag, char*& data, int &data_length, ImageFileType &image_file_type) {
+//    data = NULL;
+//    data_length = 0;
+//    image_file_type = IMAGE_FILE_TYPE_UNKNOWN;
+//    if(asftag) {
+//        if(asftag->attributeListMap().contains(PICTURE_FLAG)) {
+//            ASF::Attribute attr = asftag->attributeListMap()[PICTURE_FLAG].front();
+//            ASF::Picture pict = attr.toPicture();
+//            if(!pict.isValid())
+//                return false;
+//            
+//            ByteVector PictureData = pict.picture();
+//            
+//            if(PictureData.size() > 0) {
+//                data_length = PictureData.size();
+//                data = new char[data_length];
+//                memcpy(data, PictureData.data(), PictureData.size());
+//                
+//                String mimetype = pict.mimeType();
+//                if(mimetype.find("/jpeg") != -1 || mimetype.find("/jpg") != -1)
+//                    image_file_type = IMAGE_FILE_TYPE_JPEG;
+//                else if(mimetype.find("/png") != -1)
+//                    image_file_type = IMAGE_FILE_TYPE_PNG;
+//                
+//                return true;
+//            }
+//        }
+//    }
+//    return false;
+//}
+
+
+void set_asf_images(ASF::Tag * asftag, const Image ** images, const int image_count) {
     if(asftag) {
-        if(asftag->attributeListMap().contains("WM/Picture"))
-            asftag->removeItem("WM/Picture");
-        
-        if(!data || data_length == 0)
-            return true;
-        
-        ASF::Picture picture = ASF::Picture();
-        if(image_file_type == IMAGE_FILE_TYPE_JPEG || image_file_type == IMAGE_FILE_TYPE_UNKNOWN) //default to jpeg
-            picture.setMimeType("image/jpeg");
-        if(image_file_type == IMAGE_FILE_TYPE_PNG)
-            picture.setMimeType("image/png");
+        if(asftag->attributeListMap().contains(PICTURE_FLAG))
+            asftag->removeItem(PICTURE_FLAG);
         
-        ByteVector ImgData = ByteVector((TagLib::uint) data_length);
-        memcpy(ImgData.data(), data, data_length);
         
-        picture.setPicture(ImgData);
-        ASF::Attribute attr = ASF::Attribute(picture);
-        asftag->setAttribute("WM/Picture", attr);
-        
-        return true;
+        for(int p = 0; p < image_count; p++) {
+            const Image * image = images[p];
+            if(!image->data || image->data_length == 0)
+                continue;
+            ASF::Picture picture = ASF::Picture();
+            if(image->image_file_type == IMAGE_FILE_TYPE_JPEG || 
+               image->image_file_type == IMAGE_FILE_TYPE_UNKNOWN) //default to jpeg
+                picture.setMimeType("image/jpeg");
+            if(image->image_file_type == IMAGE_FILE_TYPE_PNG)
+                picture.setMimeType("image/png");
+            
+            ByteVector ImgData = ByteVector((TagLib::uint) image->data_length);
+            memcpy(ImgData.data(), image->data, image->data_length);
+            
+            picture.setPicture(ImgData);
+            ASF::Attribute attr = ASF::Attribute(picture);
+            asftag->setAttribute(PICTURE_FLAG, attr);
+        }
     }
-    return false;
 }
 
+
+//bool set_asf_image(ASF::Tag * asftag, const char* data, int data_length, ImageFileType image_file_type) {
+//    if(asftag) {
+//        if(asftag->attributeListMap().contains(PICTURE_FLAG))
+//            asftag->removeItem(PICTURE_FLAG);
+//        
+//        if(!data || data_length == 0)
+//            return true;
+//        
+//        ASF::Picture picture = ASF::Picture();
+//        if(image_file_type == IMAGE_FILE_TYPE_JPEG || image_file_type == IMAGE_FILE_TYPE_UNKNOWN) //default to jpeg
+//            picture.setMimeType("image/jpeg");
+//        if(image_file_type == IMAGE_FILE_TYPE_PNG)
+//            picture.setMimeType("image/png");
+//        
+//        ByteVector ImgData = ByteVector((TagLib::uint) data_length);
+//        memcpy(ImgData.data(), data, data_length);
+//        
+//        picture.setPicture(ImgData);
+//        ASF::Attribute attr = ASF::Attribute(picture);
+//        asftag->setAttribute(PICTURE_FLAG, attr);
+//        
+//        return true;
+//    }
+//    return false;
+//}
+
 ASFInfo::ASFInfo(const String &filename) : Info(filename) {
     if(!file_name.isEmpty() && !create_file_ref())
         printf("Error creating file ref! %s\n", filename.toCString());
 
 
 
+
 Image ** ASFInfo::get_images(int &image_count) const {
+    if(asf_tag) {
+        image_count = 0;
+        List<Image *> imagelist = get_asf_images(asf_tag);
+        int cnt = imagelist.size();
+        if(cnt > 0) {
+            Image** images = new Image*[cnt];
+            for(List<Image *>::Iterator it = imagelist.begin(); it != imagelist.end(); ++it) {
+                images[image_count] = (*it);
+                image_count++;
+            }
+            return images;
+        }
+    }
     return NULL;
 }
 
 void ASFInfo::set_images(const Image ** images, const int image_count) {
-    return;
+    if(asf_tag)
+        set_asf_images(asf_tag, images, image_count);
 }
-//bool ASFInfo::can_handle_images(void) const{
-//    return true;
-//}
+
 
 //bool ASFInfo::get_image(char*& data, int &data_length, ImageFileType &image_file_type) const {
 //    if(asf_tag) {

File libtaginfo/flacinfo.cc

 
 
 Image ** FlacInfo::get_images(int &image_count) const {
+    if(xiphcomment) {
+        image_count = 0;
+        List<Image *> imagelist = get_xiph_comment_images(xiphcomment);
+        int cnt = imagelist.size();
+        if(cnt > 0) {
+            Image** images = new Image*[cnt];
+            for(List<Image *>::Iterator it = imagelist.begin(); it != imagelist.end(); ++it) {
+                images[image_count] = (*it);
+                image_count++;
+            }
+            return images;
+        }
+    }
     return NULL;
 }
 
 void FlacInfo::set_images(const Image ** images, const int image_count) {
-    return;
+    if(xiphcomment)
+        set_xiph_comment_images(xiphcomment, images, image_count);
 }
 
-//bool FlacInfo::can_handle_images(void) const {
-//    return true;
-//}
-
-//bool FlacInfo::get_image(char*& data, int &data_length, ImageFileType &image_file_type) const {
-//    data = NULL;
-//    data_length = 0;
-//    image_file_type = IMAGE_FILE_TYPE_UNKNOWN;
-//    return get_xiph_comment_cover_art(xiphcomment, data, data_length, image_file_type);
-//}
-
-//bool FlacInfo::set_image(const char* data, int data_length, ImageFileType image_file_type) {
-//    if(xiphcomment)
-//        return set_xiph_comment_cover_art(xiphcomment, data, data_length, image_file_type);
-//    
-//    return false;
-//}
-
 
 bool FlacInfo::can_handle_lyrics(void) const {
     return true;

File libtaginfo/info.cc

         return String();
 }
 
+void Info::set_encoder(const String new_encoder) {
+    encoder = new_encoder;
+    changedflag |= CHANGED_ENCODER_TAG;
+}
+String Info::get_encoder() const {
+    if(String::null != encoder)
+        return encoder;
+    else
+        return String();
+}
+
 void Info::set_homepage(const String new_homepage) {
     homepage = new_homepage;
     changedflag |= CHANGED_HOMEPAGE_TAG;
     return has_image;
 }
 
-
 Image ** Info::get_images(int &image_count) const {
     return NULL;
 }
     return;
 }
 
-//bool Info::can_handle_images() const {
-//    return false;
-//}
-
-//bool Info::get_image(char*& data, int &data_length, ImageFileType &image_file_type) const {
-//    data = NULL;
-//    data_length = 0;
-//    image_file_type = IMAGE_FILE_TYPE_UNKNOWN;
-//    return false;
-//}
-
-//bool Info::set_image(const char* data, int data_length, ImageFileType image_file_type) {
-//    return false;
-//}
-
-
 bool Info::can_handle_lyrics() const {
     return false;
 }
 
-
 String Info::get_lyrics() const {
     return String();
 }

File libtaginfo/mp3info.cc

 }
 
 
-//bool Mp3Info::get_images(Image *& imgs, int &image_count) const {
 Image ** Mp3Info::get_images(int &image_count) const {
     if(taglib_tagId3v2) {
         image_count = 0;
 void Mp3Info::set_images(const Image ** images, const int image_count) {
     if(taglib_tagId3v2) {
         set_id3v2_images(taglib_tagId3v2, images, image_count);
-//        TagLib::ID3v2::AttachedPictureFrame * PicFrame = NULL;
-//        TagLib::ID3v2::FrameList frameList = taglib_tagId3v2->frameListMap()["APIC"];
-//        for(int p = 0; p < image_count; p++) {
-//            if(!images[p]->data || images[p]->data_length == 0)
-//                continue;
-//            
-//            for(list<TagLib::ID3v2::Frame*>::iterator iter = frameList.begin(); iter != frameList.end(); iter++) {
-//                PicFrame = static_cast<TagLib::ID3v2::AttachedPictureFrame *>(*iter);
-//                    if((PicFrame->type() == image_type_to_picframetype(images[p]->image_type)))
-//                    taglib_tagId3v2->removeFrame(PicFrame, true);
-//            }
-//            
-//            PicFrame = new TagLib::ID3v2::AttachedPictureFrame;
-//            if(images[p]->image_file_type == IMAGE_FILE_TYPE_JPEG || 
-//               images[p]->image_file_type == IMAGE_FILE_TYPE_UNKNOWN) //default to jpeg
-//                PicFrame->setMimeType("image/jpeg");
-//            if(images[p]->image_file_type == IMAGE_FILE_TYPE_PNG)
-//                PicFrame->setMimeType("image/png");
-//            PicFrame->setType(image_type_to_picframetype(images[p]->image_type));
-//            ByteVector ImgData((TagLib::uint) images[p]->data_length);
-//            memcpy(ImgData.data(), images[p]->data, images[p]->data_length);
-//            PicFrame->setPicture(ImgData);
-//            taglib_tagId3v2->addFrame(PicFrame);
-//        }
     }
 }
 
 
-//bool Mp3Info::can_handle_images(void) const {
-//    return true;
-//}
-
-//bool Mp3Info::get_image(char*& data, int &data_length, ImageFileType &image_file_type) const {
-//    data = NULL;
-//    data_length = 0;
-//    image_file_type = IMAGE_FILE_TYPE_UNKNOWN;
-//    
-//    if(taglib_tagId3v2)
-//        return get_id3v2_image(taglib_tagId3v2, data, data_length, image_file_type);
-//    
-//    return false;
-//}
-
-//bool Mp3Info::set_image(const char* data, int data_length, ImageFileType image_file_type) {
-//    if(taglib_tagId3v2)
-//        set_id3v2_image(taglib_tagId3v2, data, data_length, image_file_type);
-//    return true;
-//}
-
-
 bool Mp3Info::can_handle_lyrics(void) const {
     return true;
 }

File libtaginfo/mp4_common.cc

 #include <mp4file.h>
 
 
-bool get_mp4_cover_art(TagLib::MP4::Tag * mp4tag, char*& data, int &data_length, ImageFileType &image_file_type) {
-    data = NULL;
-    data_length = 0;
-    image_file_type = IMAGE_FILE_TYPE_UNKNOWN;
-    
+List<Image *> get_mp4_images(TagLib::MP4::Tag * mp4tag) {
+    List<Image *> images;
     if(mp4tag && mp4tag->itemListMap().contains("covr")) {
         TagLib::MP4::CoverArtList Covers = mp4tag->itemListMap()[ "covr" ].toCoverArtList();
-        
+        Image * image = NULL;
         for(TagLib::MP4::CoverArtList::Iterator it = Covers.begin(); it != Covers.end(); it++) {
+            image = new Image();
+            image->image_type = IMAGE_TYPE_COVER_FRONT; // is it possible to distinguish?
+            image->data_length = it->data().size();
+            image->data = new char[image->data_length];
+            memcpy(image->data, it->data().data(), it->data().size());
+            
             if(it->format() == TagLib::MP4::CoverArt::PNG) {
-                image_file_type = IMAGE_FILE_TYPE_PNG;
+                image->image_file_type = IMAGE_FILE_TYPE_PNG;
             }
             else if(it->format() == TagLib::MP4::CoverArt::JPEG) {
-                image_file_type = IMAGE_FILE_TYPE_JPEG;
+                image->image_file_type = IMAGE_FILE_TYPE_JPEG;
             }
-            data_length = it->data().size();
-            data = new char[data_length];
-            memcpy(data, it->data().data(), it->data().size());
-            return true;
+            else {
+                image->image_file_type = IMAGE_FILE_TYPE_UNKNOWN;
+            }
+            if(image->data && image->data_length > 0)
+                images.prepend(image);
         }
-        return false;
     }
-    return false;
+    return images;
 }
 
 
-bool set_mp4_cover_art(TagLib::MP4::Tag * mp4tag, const char* data, int data_length, ImageFileType image_file_type) {
+//bool get_mp4_cover_art(TagLib::MP4::Tag * mp4tag, char*& data, int &data_length, ImageFileType &image_file_type) {
+//    data = NULL;
+//    data_length = 0;
+//    image_file_type = IMAGE_FILE_TYPE_UNKNOWN;
+//    
+//    if(mp4tag && mp4tag->itemListMap().contains("covr")) {
+//        TagLib::MP4::CoverArtList Covers = mp4tag->itemListMap()[ "covr" ].toCoverArtList();
+//        
+//        for(TagLib::MP4::CoverArtList::Iterator it = Covers.begin(); it != Covers.end(); it++) {
+//            if(it->format() == TagLib::MP4::CoverArt::PNG) {
+//                image_file_type = IMAGE_FILE_TYPE_PNG;
+//            }
+//            else if(it->format() == TagLib::MP4::CoverArt::JPEG) {
+//                image_file_type = IMAGE_FILE_TYPE_JPEG;
+//            }
+//            data_length = it->data().size();
+//            data = new char[data_length];
+//            memcpy(data, it->data().data(), it->data().size());
+//            return true;
+//        }
+//        return false;
+//    }
+//    return false;
+//}
+
+void set_mp4_images(TagLib::MP4::Tag * mp4tag, const Image ** images, const int image_count) {
     if(mp4tag) {
         if(mp4tag->itemListMap().contains("covr")) {
             mp4tag->itemListMap().erase("covr");
         }
-        if(data && data_length > 0) {
-            ByteVector image_data((TagLib::uint) data_length);
-            memcpy(image_data.data(), data, data_length);
-            TagLib::MP4::CoverArtList cover_list;
-            TagLib::MP4::CoverArt::Format format = TagLib::MP4::CoverArt::JPEG;
-            if(image_file_type == IMAGE_FILE_TYPE_JPEG || image_file_type == IMAGE_FILE_TYPE_UNKNOWN) //default to jpeg
-                format = TagLib::MP4::CoverArt::JPEG;
-            if(image_file_type == IMAGE_FILE_TYPE_PNG)
-                format = TagLib::MP4::CoverArt::PNG;
-            TagLib::MP4::CoverArt cover(format, image_data);
-            cover_list.append(cover);
-            mp4tag->itemListMap()[ "covr" ] = cover_list;
-            return true;
+        TagLib::MP4::CoverArtList cover_list;
+        for(int p = 0; p < image_count; p++) {
+            const Image * image = images[p];
+            if(image->data && image->data_length > 0) {
+                ByteVector image_data((TagLib::uint) image->data_length);
+                memcpy(image_data.data(), image->data, image->data_length);
+                TagLib::MP4::CoverArt::Format format = TagLib::MP4::CoverArt::JPEG;
+                if(image->image_file_type == IMAGE_FILE_TYPE_JPEG || image->image_file_type == IMAGE_FILE_TYPE_UNKNOWN) //default to jpeg
+                    format = TagLib::MP4::CoverArt::JPEG;
+                if(image->image_file_type == IMAGE_FILE_TYPE_PNG)
+                    format = TagLib::MP4::CoverArt::PNG;
+                TagLib::MP4::CoverArt cover(format, image_data);
+                cover_list.append(cover);
+            }
         }
-        return true;
+        if(0 < cover_list.size())
+            mp4tag->itemListMap()[ "covr" ] = cover_list;
     }
-    return false;
 }
 
+//bool set_mp4_cover_art(TagLib::MP4::Tag * mp4tag, const char* data, int data_length, ImageFileType image_file_type) {
+//    if(mp4tag) {
+//        if(mp4tag->itemListMap().contains("covr")) {
+//            mp4tag->itemListMap().erase("covr");
+//        }
+//        if(data && data_length > 0) {
+//            ByteVector image_data((TagLib::uint) data_length);
+//            memcpy(image_data.data(), data, data_length);
+//            TagLib::MP4::CoverArtList cover_list;
+//            TagLib::MP4::CoverArt::Format format = TagLib::MP4::CoverArt::JPEG;
+//            if(image_file_type == IMAGE_FILE_TYPE_JPEG || image_file_type == IMAGE_FILE_TYPE_UNKNOWN) //default to jpeg
+//                format = TagLib::MP4::CoverArt::JPEG;
+//            if(image_file_type == IMAGE_FILE_TYPE_PNG)
+//                format = TagLib::MP4::CoverArt::PNG;
+//            TagLib::MP4::CoverArt cover(format, image_data);
+//            cover_list.append(cover);
+//            mp4tag->itemListMap()[ "covr" ] = cover_list;
+//            return true;
+//        }
+//        return true;
+//    }
+//    return false;
+//}
+
 String get_mp4_lyrics(TagLib::MP4::Tag * mp4tag) {
     if(mp4tag) {
             if(mp4tag->itemListMap().contains("\xa9lyr"))

File libtaginfo/mp4info.cc

     return Info::write();
 }
 
-
 Image ** Mp4Info::get_images(int &image_count) const {
+    if(mp4_tag) {
+        image_count = 0;
+        List<Image *> imagelist = get_mp4_images(mp4_tag);
+        int cnt = imagelist.size();
+        if(cnt > 0) {
+            Image** images = new Image*[cnt];
+            for(List<Image *>::Iterator it = imagelist.begin(); it != imagelist.end(); ++it) {
+                images[image_count] = (*it);
+                image_count++;
+            }
+            return images;
+        }
+    }
     return NULL;
 }
 
 void Mp4Info::set_images(const Image ** images, const int image_count) {
-    return;
+    if(mp4_tag)
+        set_mp4_images(mp4_tag, images, image_count);
 }
 
+
 //bool Mp4Info::can_handle_images(void) const {
 //    return true;
 //}

File libtaginfo/mpcinfo.cc

 }
 
 
-
 Image ** MpcInfo::get_images(int &image_count) const {
+    if(taglib_apetag) {
+        image_count = 0;
+        List<Image *> imagelist = get_ape_images(taglib_apetag);
+        int cnt = imagelist.size();
+        if(cnt > 0) {
+            Image** images = new Image*[cnt];
+            for(List<Image *>::Iterator it = imagelist.begin(); it != imagelist.end(); ++it) {
+                images[image_count] = (*it);
+                image_count++;
+            }
+            return images;
+        }
+    }
     return NULL;
 }
 
 void MpcInfo::set_images(const Image ** images, const int image_count) {
-    return;
+    if(taglib_apetag)
+        set_ape_images(taglib_apetag, images, image_count);
 }
-//bool MpcInfo::can_handle_images(void) const {
-//    return true;
-//}
-
-//bool MpcInfo::get_image(char*& data, int &data_length, ImageFileType &image_file_type) const {
-//    if(taglib_apetag) {
-//        return get_ape_image(taglib_apetag, data, data_length, image_file_type);
-//    }
-//    return false;
-//}
-
-//bool MpcInfo::set_image(const char* data, int data_length, ImageFileType image_file_type) {
-//    return taglib_apetag && set_ape_image(taglib_apetag, data, data_length, image_file_type);
-//}
 
 
 bool MpcInfo::can_handle_lyrics(void) const {

File libtaginfo/ogginfo.cc

         set_xiph_comment_images(xiphcomment, images, image_count);
 }
 
-//bool OggInfo::can_handle_images(void) const {
-//    return true;
-//}
-
-//bool OggInfo::get_image(char*& data, int &data_length, ImageFileType &image_file_type) const {
-//    data = NULL;
-//    data_length = 0;
-//    return get_xiph_comment_cover_art(xiphcomment, data, data_length, image_file_type);
-//}
-
-//bool OggInfo::set_image(const char* data, int data_length, ImageFileType image_file_type) {
-//    return set_xiph_comment_cover_art(xiphcomment, data, data_length, image_file_type);
-//}
-
 bool OggInfo::can_handle_lyrics(void) const {
     return true;
 }

File libtaginfo/speexinfo.cc

     return Info::write();
 }
 
-
 Image ** SpeexInfo::get_images(int &image_count) const {
+    if(xiphcomment) {
+        image_count = 0;
+        List<Image *> imagelist = get_xiph_comment_images(xiphcomment);
+        int cnt = imagelist.size();
+        if(cnt > 0) {
+            Image** images = new Image*[cnt];
+            for(List<Image *>::Iterator it = imagelist.begin(); it != imagelist.end(); ++it) {
+                images[image_count] = (*it);
+                image_count++;
+            }
+            return images;
+        }
+    }
     return NULL;
 }
 
 void SpeexInfo::set_images(const Image ** images, const int image_count) {
-    return;
+    if(xiphcomment)
+        set_xiph_comment_images(xiphcomment, images, image_count);
 }
 
-//bool SpeexInfo::can_handle_images(void) const {
-//    return true;
-//}
-
-//bool SpeexInfo::get_image(char*& data, int &data_length, ImageFileType &image_file_type) const {
-//    data = NULL;
-//    data_length = 0;
-//    return get_xiph_comment_cover_art(xiphcomment, data, data_length, image_file_type);
-//}
-
-//bool SpeexInfo::set_image(const char* data, int data_length, ImageFileType image_file_type) {
-//    return set_xiph_comment_cover_art(xiphcomment, data, data_length, image_file_type);
-//}
 
 bool SpeexInfo::can_handle_lyrics(void) const {
     return true;

File libtaginfo/taginfo.h

             String composer;
             String comments;
             String homepage;
+            String encoder;
             int    tracknumber;
             int    year;
             bool   is_compilation;
             String get_homepage(void) const;
             void   set_homepage(const String new_homepage);
             
+            String get_encoder(void) const;
+            void   set_encoder(const String new_encoder);
+            
             int  get_playcount() const;
             void set_playcount(int new_playcount);
             

File libtaginfo/taginfo_internal.h

         CHANGED_ARTIST_LABELS      = (1 << 16),
         CHANGED_ALBUM_LABELS       = (1 << 17),
         CHANGED_IS_COMPILATION_TAG = (1 << 18),
-        CHANGED_HOMEPAGE_TAG       = (1 << 19)
+        CHANGED_HOMEPAGE_TAG       = (1 << 19),
+        CHANGED_ENCODER_TAG        = (1 << 20)
     };
 }
 
 
 void check_ape_label_frame(TagLib::APE::Tag * apetag, const char * description, const String &value);
 
-bool get_ape_item_image(const TagLib::APE::Item &item, char*& data, int &data_length, ImageFileType &image_file_type);
-bool get_ape_image(TagLib::APE::Tag * apetag, char*& data, int &data_length, ImageFileType &image_file_type);
-bool set_ape_image(TagLib::APE::Tag * apetag, const char* data, int data_length, ImageFileType image_file_type);
+void get_ape_item_image(const TagLib::APE::Item &item, char*& data, int &data_length, ImageFileType &image_file_type);
+
+List<Image *>  get_ape_images(TagLib::APE::Tag * apetag);
+void set_ape_images(TagLib::APE::Tag * apetag, const Image ** images, const int image_count);
 
 String get_ape_lyrics(APE::Tag * apetag);
 bool set_ape_lyrics(APE::Tag * apetag, const String &lyrics);
 List<Image *> get_id3v2_images(ID3v2::Tag * tagv2);
 void set_id3v2_images(ID3v2::Tag * taglib_tagId3v2, const Image ** images, const int image_count);
 
-bool get_id3v2_image(ID3v2::Tag * tagv2, char*& data, int &data_length, ImageFileType &image_file_type);
-void set_id3v2_image(ID3v2::Tag * tagv2, const char* data, int data_length, ImageFileType image_file_type);
-
 String get_id3v2_lyrics(ID3v2::Tag * tagv2);
 void set_id3v2_lyrics(ID3v2::Tag * tagv2, const String &lyrics);
 
 
 ////////// MP4
 
-bool get_mp4_cover_art(TagLib::MP4::Tag * mp4tag, char*& data, int &data_length, ImageFileType &image_file_type);
-bool set_mp4_cover_art(TagLib::MP4::Tag * mp4tag, const char* data, int data_length, ImageFileType image_file_type);
+//bool get_mp4_cover_art(TagLib::MP4::Tag * mp4tag, char*& data, int &data_length, ImageFileType &image_file_type);
+//bool set_mp4_cover_art(TagLib::MP4::Tag * mp4tag, const char* data, int data_length, ImageFileType image_file_type);
+List<Image *>  get_mp4_images(TagLib::MP4::Tag * mp4tag);
+void set_mp4_images(TagLib::MP4::Tag * mp4tag, const Image ** images, const int image_count);
 
 String get_mp4_lyrics(TagLib::MP4::Tag * mp4tag);
 bool set_mp4_lyrics(TagLib::MP4::Tag * mp4tag, const String &lyrics);
 List<Image *>  get_xiph_comment_images(Ogg::XiphComment * xiphcomment);
 void set_xiph_comment_images(Ogg::XiphComment * xiphcomment, const Image ** images, const int image_count);
 
-bool get_xiph_comment_cover_art(Ogg::XiphComment * xiphcomment, 
-                                char*& data, int &data_length, 
-                                ImageFileType &image_file_type);
-bool set_xiph_comment_cover_art(Ogg::XiphComment * xiphcomment, 
-                                const char* data, int data_length,
-                                ImageFileType image_file_type);
 
 ////////// end XIPH
 

File libtaginfo/trueaudioinfo.cc

 
 
 Image ** TrueAudioInfo::get_images(int &image_count) const {
+    if(taglib_tagId3v2) {
+        image_count = 0;
+        List<Image *> imagelist = get_id3v2_images(taglib_tagId3v2);
+        int cnt = imagelist.size();
+        if(cnt > 0) {
+            Image** images = new Image*[cnt];
+            for(List<Image *>::Iterator it = imagelist.begin(); it != imagelist.end(); ++it) {
+                images[image_count] = (*it);
+                image_count++;
+            }
+            return images;
+        }
+    }
     return NULL;
 }
 
 void TrueAudioInfo::set_images(const Image ** images, const int image_count) {
-    return;
+    if(taglib_tagId3v2) {
+        set_id3v2_images(taglib_tagId3v2, images, image_count);
+    }
 }
 
-//bool TrueAudioInfo::can_handle_images(void) const {
-//    return true;
-//}
-
-//bool TrueAudioInfo::get_image(char*& data, int &data_length, ImageFileType &image_file_type) const {
-//    if(taglib_tagId3v2)
-//        return get_id3v2_image(taglib_tagId3v2, data, data_length, image_file_type);
-//    return false;
-//}
-
-//bool TrueAudioInfo::set_image(const char* data, int data_length, ImageFileType image_file_type) {
-//    if(taglib_tagId3v2)
-//        set_id3v2_image(taglib_tagId3v2, data, data_length, image_file_type);
-//    return true;
-//}
-
 bool TrueAudioInfo::can_handle_lyrics(void) const {
     return true;
 }

File libtaginfo/waveinfo.cc

 }
 
 
-
 Image ** WaveInfo::get_images(int &image_count) const {
+    if(taglib_tagId3v2) {
+        image_count = 0;
+        List<Image *> imagelist = get_id3v2_images(taglib_tagId3v2);
+        int cnt = imagelist.size();
+        if(cnt > 0) {
+            Image** images = new Image*[cnt];
+            for(List<Image *>::Iterator it = imagelist.begin(); it != imagelist.end(); ++it) {
+                images[image_count] = (*it);
+                image_count++;
+            }
+            return images;
+        }
+    }
     return NULL;
 }
 
 void WaveInfo::set_images(const Image ** images, const int image_count) {
-    return;
+    if(taglib_tagId3v2) {
+        set_id3v2_images(taglib_tagId3v2, images, image_count);
+    }
 }
 //bool WaveInfo::can_handle_images(void) const {
 //    return true;

File libtaginfo/wavpackinfo.cc

 
 
 Image ** WavPackInfo::get_images(int &image_count) const {
+    if(taglib_apetag && !taglib_apetag->isEmpty()) {
+        image_count = 0;
+        List<Image *> imagelist = get_ape_images(taglib_apetag);
+        int cnt = imagelist.size();
+        if(cnt > 0) {
+            Image** images = new Image*[cnt];
+            for(List<Image *>::Iterator it = imagelist.begin(); it != imagelist.end(); ++it) {
+                images[image_count] = (*it);
+                image_count++;
+            }
+            return images;
+        }
+    }
     return NULL;
 }
 
 void WavPackInfo::set_images(const Image ** images, const int image_count) {
+    if(taglib_apetag)
+        set_ape_images(taglib_apetag, images, image_count);
     return;
 }
 
-//bool WavPackInfo::can_handle_images(void) const {
-//    return false;
-//}
-
-//bool WavPackInfo::get_image(char*& data, int &data_length, ImageFileType &image_file_type) const {
-//    return get_ape_image(taglib_apetag, data, data_length, image_file_type);
-//}
-
-//bool WavPackInfo::set_image(const char* data, int data_length, ImageFileType image_file_type) {
-//    return set_ape_image(taglib_apetag, data, data_length, image_file_type);
-//}
-
 
 bool WavPackInfo::can_handle_lyrics(void) const {
     return true;

File libtaginfo/xiph_common.cc

     return images;
 }
 
-bool get_xiph_comment_cover_art(Ogg::XiphComment * xiphcomment, 
-                                char*& data, int &data_length, 
-                                ImageFileType &image_file_type) {
-    if(xiphcomment && xiphcomment->contains("COVERART")) {
-        String mimetype = xiphcomment->fieldListMap()[ "COVERARTMIME" ].front().to8Bit(false);
-        if(mimetype.find("/jpeg") != -1 || mimetype.find("/jpg") != -1)
-            image_file_type = IMAGE_FILE_TYPE_JPEG;
-        else if(mimetype.find("/png") != -1)
-            image_file_type = IMAGE_FILE_TYPE_PNG;
-        
-        // TODO: deprecated, use METADATA_BLOCK_PICTURE 
-        const char* CoverEncData = xiphcomment->fieldListMap()[ "COVERART" ].front().toCString(true); 
-        
-        string CoverDecData = base64_decode(CoverEncData);
-        
-        data_length = CoverDecData.size();
-        data = new char[data_length];
-        memcpy(data, CoverDecData.data(), CoverDecData.size());
-        
-        return true;
-    }
-    return false;
-}
+//bool get_xiph_comment_cover_art(Ogg::XiphComment * xiphcomment, 
+//                                char*& data, int &data_length, 
+//                                ImageFileType &image_file_type) {
+//    if(xiphcomment && xiphcomment->contains("COVERART")) {
+//        String mimetype = xiphcomment->fieldListMap()[ "COVERARTMIME" ].front().to8Bit(false);
+//        if(mimetype.find("/jpeg") != -1 || mimetype.find("/jpg") != -1)
+//            image_file_type = IMAGE_FILE_TYPE_JPEG;
+//        else if(mimetype.find("/png") != -1)
+//            image_file_type = IMAGE_FILE_TYPE_PNG;
+//        
+//        // TODO: deprecated, use METADATA_BLOCK_PICTURE 
+//        const char* CoverEncData = xiphcomment->fieldListMap()[ "COVERART" ].front().toCString(true); 
+//        
+//        string CoverDecData = base64_decode(CoverEncData);
+//        
+//        data_length = CoverDecData.size();
+//        data = new char[data_length];
+//        memcpy(data, CoverDecData.data(), CoverDecData.size());
+//        
+//        return true;
+//    }
+//    return false;
+//}
 
 void set_xiph_comment_images(Ogg::XiphComment * xiphcomment, const Image ** images, const int image_count) {
     if(xiphcomment) {
             xiphcomment->removeField("COVERARTMIME");
             xiphcomment->removeField("COVERART");
         }
-        const Image * image = images[0];
-        if(image && image->data && image->data_length > 0) {
-            if(image->image_file_type == IMAGE_FILE_TYPE_UNKNOWN || image->image_file_type == IMAGE_FILE_TYPE_JPEG)
-                xiphcomment->addField("COVERARTMIME", "image/jpeg");
-            else if(image->image_file_type == IMAGE_FILE_TYPE_PNG)
-                xiphcomment->addField("COVERARTMIME", "image/png");
-            xiphcomment->addField("COVERART", base64encode(image->data, image->data_length).toCString(false));
+        for(int p = 0; p < image_count; p++) {
+            const Image * image = images[p];
+            if(image && image->data && image->data_length > 0) {
+                if(image->image_file_type == IMAGE_FILE_TYPE_UNKNOWN || image->image_file_type == IMAGE_FILE_TYPE_JPEG)
+                    xiphcomment->addField("COVERARTMIME", "image/jpeg");
+                else if(image->image_file_type == IMAGE_FILE_TYPE_PNG)
+                    xiphcomment->addField("COVERARTMIME", "image/png");
+                
+                xiphcomment->addField("COVERART", 
+                                      base64encode(image->data, image->data_length).toCString(false));
+            }
         }
     }
 }

File tests/Makefile.am

     write_wma/test \
     ctest_read/test \
     ctest_write/test \
+    write_image_ape/test \
+    write_image_flac/test \
     write_image_mp3/test \
-    write_image_ogg/test
-#    write_image_ape/test
-#    write_image_flac/test
-#    write_image_mp4/test
-#    write_image_mpc/test
-#    write_image_speex/test
-#    write_image_tta/test
-#    write_image_wav/test
-#    write_image_wma/test
-#    write_image_wv/test
+    write_image_mp4/test \
+    write_image_mpc/test \
+    write_image_ogg/test \
+    write_image_speex/test \
+    write_image_tta/test \
+    write_image_wav/test \
+    write_image_wma/test \
+    write_image_wv/test
 
 TESTS = $(check_PROGRAMS)
 
 ctest_write_test_SOURCES        = ctest_write/main.c
 ctest_write_test_LDADD          = $(top_builddir)/bindings/c/libtaginfo_c.la
 
-#write_image_ape_test_SOURCES    = write_image_ape/main.cc
-#write_image_ape_test_LDADD      = $(taginfo_ldadd)
+write_image_ape_test_SOURCES    = write_image_ape/main.cc
+write_image_ape_test_LDADD      = $(taginfo_ldadd)
 
-#write_image_flac_test_SOURCES   = write_image_flac/main.cc
-#write_image_flac_test_LDADD     = $(taginfo_ldadd)
+write_image_flac_test_SOURCES   = write_image_flac/main.cc
+write_image_flac_test_LDADD     = $(taginfo_ldadd)
 
 write_image_mp3_test_SOURCES    = write_image_mp3/main.cc
 write_image_mp3_test_LDADD      = $(taginfo_ldadd)
 
-#write_image_mp4_test_SOURCES    = write_image_mp4/main.cc
-#write_image_mp4_test_LDADD      = $(taginfo_ldadd)
+write_image_mp4_test_SOURCES    = write_image_mp4/main.cc
+write_image_mp4_test_LDADD      = $(taginfo_ldadd)
 
-#write_image_mpc_test_SOURCES    = write_image_mpc/main.cc
-#write_image_mpc_test_LDADD      = $(taginfo_ldadd)
+write_image_mpc_test_SOURCES    = write_image_mpc/main.cc
+write_image_mpc_test_LDADD      = $(taginfo_ldadd)
 
 write_image_ogg_test_SOURCES    = write_image_ogg/main.cc
 write_image_ogg_test_LDADD      = $(taginfo_ldadd)
 
-#write_image_speex_test_SOURCES  = write_image_speex/main.cc
-#write_image_speex_test_LDADD    = $(taginfo_ldadd)
+write_image_speex_test_SOURCES  = write_image_speex/main.cc
+write_image_speex_test_LDADD    = $(taginfo_ldadd)
 
-#write_image_tta_test_SOURCES    = write_image_tta/main.cc
-#write_image_tta_test_LDADD      = $(taginfo_ldadd)
+write_image_tta_test_SOURCES    = write_image_tta/main.cc
+write_image_tta_test_LDADD      = $(taginfo_ldadd)
 
-#write_image_wav_test_SOURCES    = write_image_wav/main.cc
-#write_image_wav_test_LDADD      = $(taginfo_ldadd)
+write_image_wav_test_SOURCES    = write_image_wav/main.cc
+write_image_wav_test_LDADD      = $(taginfo_ldadd)
 
-#write_image_wma_test_SOURCES    = write_image_wma/main.cc
-#write_image_wma_test_LDADD      = $(taginfo_ldadd)
+write_image_wma_test_SOURCES    = write_image_wma/main.cc
+write_image_wma_test_LDADD      = $(taginfo_ldadd)
 
-#write_image_wv_test_SOURCES     = write_image_wv/main.cc
-#write_image_wv_test_LDADD       = $(taginfo_ldadd)
+write_image_wv_test_SOURCES     = write_image_wv/main.cc
+write_image_wv_test_LDADD       = $(taginfo_ldadd)
 
 DISTCLEANFILES = \
     Makefile.in

File tests/write_image_ape/main.cc

 #include <sys/stat.h>
 
 using namespace TagInfo;
-//using namespace std;
 
-void clean_up(char* map, int size, int fd) {
-    if(munmap(map, size) == -1) {
-        perror("Error un-mmapping the file");
-    }
-    if(fd != 0)
-        close(fd);
-}
 
 int main( void ) {
     Info * info;
     std::ofstream  dst(target.c_str());
     dst << src.rdbuf();
     
-    char* data;
-    int data_length;
-    ImageFileType image_file_type = IMAGE_FILE_TYPE_JPEG;
+    Image * img = new Image();
+    img->image_file_type = IMAGE_FILE_TYPE_JPEG;
+    img->image_type      = IMAGE_TYPE_OTHER;
     
     struct stat filestatus;
     stat( image.c_str(), &filestatus );
     //cout << filestatus.st_size << " bytes\n";
-    data_length = filestatus.st_size;
+    img->data_length = filestatus.st_size;
     int fd;
     
     fd = open(image.c_str(), O_RDONLY);
         perror("Error opening file for reading");
         EXIT_FAILURE;
     }
-    data = (char*)mmap(0, data_length, PROT_READ, MAP_SHARED, fd, 0);
-    if(data == MAP_FAILED) {
+    
+    img->data = (char*)mmap(0, img->data_length, PROT_READ, MAP_SHARED, fd, 0);
+    if(img->data == MAP_FAILED) {
         close(fd);
         perror("Error mmapping the file");
         EXIT_FAILURE;
     
     info = Info::create_tag_info(target);
     if(info) {
-        if(!info->set_image(data, data_length, image_file_type)) {
-            clean_up(data, data_length, fd);
-            delete info;
-            return EXIT_FAILURE;
-        }
+        Image ** imgs = new Image*[1];
+        imgs[0] = img;
+        info->set_images((const Image **)imgs, 1);
+        if(imgs)
+            delete [] imgs;
         info->write();
     }
     delete info;
     info = NULL;
     
     info = Info::create_tag_info(target);
-    char* read;
-    int read_length;
-    ImageFileType read_type;
+    Image * read_image;
     if(info) {
         if(info->read()) {
-            if(!info->get_image(read, read_length, read_type)) {
+            int len = 0;
+            Image ** images = info->get_images(len);
+            if(!images) {
                 delete info;
-                if(!read || remove(target.c_str()) != 0 ) {
-                    clean_up(data, data_length, fd);
+                if(remove(target.c_str()) != 0 ) {
+                    return EXIT_FAILURE;
+                }
+                return EXIT_FAILURE;
+            }
+            read_image = images[0];
+            if(!images[0] || !read_image) {
+                delete info;
+                if(remove(target.c_str()) != 0 ) {
+                    if(images)
+                        delete [] images;
                     return EXIT_FAILURE;
                 }
             }
             int i;
-            for(i = 0; i<data_length; i++) {
-                if(!read || data[i] != read[i]) {
-                    clean_up(data, data_length, fd);
-                    delete [] read;
+            for(i = 0; i<img->data_length; i++) {
+                if(img->data[i] != read_image->data[i]) {
+                    if(images)
+                        delete [] images;
                     return EXIT_FAILURE;
                 }
             }
-            clean_up(data, data_length, fd);
-            delete [] read;
+            if(images)
+                delete [] images;
             if(remove(target.c_str()) != 0 )
                 return EXIT_FAILURE;
             return EXIT_SUCCESS;
         }
         delete info;
-        clean_up(data, data_length, fd);
         if(remove(target.c_str()) != 0 )
             return EXIT_FAILURE;
         return EXIT_FAILURE;
     }
     else {
        delete info;
-        clean_up(data, data_length, fd);
         if(remove(target.c_str()) != 0 )
             return EXIT_FAILURE;
         return EXIT_FAILURE;
     }
     return EXIT_FAILURE;
 }
-

File tests/write_image_flac/main.cc

 #include <sys/stat.h>
 
 using namespace TagInfo;
-//using namespace std;
 
-void clean_up(char* map, int size, int fd) {
-    if(munmap(map, size) == -1) {
-        perror("Error un-mmapping the file");
-    }
-    if(fd != 0)
-        close(fd);
-}
 
 int main( void ) {
     Info * info;
     std::ofstream  dst(target.c_str());
     dst << src.rdbuf();
     
-    char* data;
-    int data_length;
-    ImageFileType image_file_type = IMAGE_FILE_TYPE_JPEG;
-    
+
+    Image * img = new Image();
+    img->image_file_type = IMAGE_FILE_TYPE_JPEG;
+    img->image_type      = IMAGE_TYPE_OTHER;
+
     struct stat filestatus;
     stat( image.c_str(), &filestatus );
     //cout << filestatus.st_size << " bytes\n";
-    data_length = filestatus.st_size;
+    img->data_length = filestatus.st_size;
     int fd;
-    
     fd = open(image.c_str(), O_RDONLY);
     if (fd == -1) {
         perror("Error opening file for reading");
         EXIT_FAILURE;
     }
     
-    data = (char*)mmap(0, data_length, PROT_READ, MAP_SHARED, fd, 0);
-    if(data == MAP_FAILED) {
+    img->data = (char*)mmap(0, img->data_length, PROT_READ, MAP_SHARED, fd, 0);
+    if(img->data == MAP_FAILED) {
         close(fd);
         perror("Error mmapping the file");
         EXIT_FAILURE;
     
     info = Info::create_tag_info(target);
     if(info) {
-        if(!info->set_image(data, data_length, image_file_type)) {
-            clean_up(data, data_length, fd);
-            delete info;
-            return EXIT_FAILURE;
-        }
+        Image ** imgs = new Image*[1];
+        imgs[0] = img;
+        info->set_images((const Image **)imgs, 1);
         info->write();
     }
     delete info;
     info = NULL;
     
     info = Info::create_tag_info(target);
-    char* read;
-    int read_length;
-    ImageFileType read_type;
+    Image * read_image = NULL;
+    
     if(info) {
         if(info->read()) {
-            if(!info->get_image(read, read_length, read_type)) {
+            int len = 0;
+            Image ** images = info->get_images(len);
+            if(!images) {
+                delete info;
+                if(remove(target.c_str()) != 0 ) {
+                    return EXIT_FAILURE;
+                }
+                return EXIT_FAILURE;
+            }
+            read_image = images[0];
+            if(!images[0] || !read_image) {
                 delete info;
                 if(remove(target.c_str()) != 0 ) {
-                    clean_up(data, data_length, fd);
+                    if(img)
+                        delete img;
                     return EXIT_FAILURE;
                 }
             }
             int i;
-            for(i = 0; i<data_length; i++) {
-                if(data[i] != read[i]) {
-                    clean_up(data, data_length, fd);
-                    delete [] read;
+            for(i = 0; i<img->data_length; i++) {
+                if(img->data[i] != read_image->data[i]) {
+                    if(images)
+                        delete [] images;
+                    if(read_image)
+                        delete read_image;
                     return EXIT_FAILURE;
                 }
             }
-            clean_up(data, data_length, fd);
-            delete [] read;
+            if(images)
+                delete [] images;
             if(remove(target.c_str()) != 0 )
                 return EXIT_FAILURE;
             return EXIT_SUCCESS;
         }
         delete info;
-        clean_up(data, data_length, fd);
         if(remove(target.c_str()) != 0 )
             return EXIT_FAILURE;
         return EXIT_FAILURE;
     }
     else {
        delete info;
-        clean_up(data, data_length, fd);
         if(remove(target.c_str()) != 0 )
             return EXIT_FAILURE;
         return EXIT_FAILURE;

File tests/write_image_mp3/main.cc

 #include <sys/stat.h>
 
 using namespace TagInfo;
-//using namespace std;
 
-void clean_up(char* map, int size, int fd) {
-    if(munmap(map, size) == -1) {
-        perror("Error un-mmapping the file");
-    }
-    if(fd != 0)
-        close(fd);
-}
 
 int main( void ) {
     Info * info;
         Image ** imgs = new Image*[1];
         imgs[0] = img;
         info->set_images((const Image **)imgs, 1);
-//        if(!info->set_images(imgs)) {
-//            clean_up(data, data_length, fd);
-//            delete info;
-//            return EXIT_FAILURE;
-//        }
+        if(imgs)
+            delete [] imgs;
         info->write();
     }
     delete info;
     
     info = Info::create_tag_info(target);
     Image * read_image;
-//    char* read;
-//    int read_length;
-//    ImageFileType read_type;
     if(info) {
         if(info->read()) {
             int len = 0;
             if(!images) {
                 delete info;
                 if(remove(target.c_str()) != 0 ) {
-//                    clean_up(data, data_length, fd);
                     return EXIT_FAILURE;
                 }
                 return EXIT_FAILURE;
             }
-//std::cout << "013" << std::endl;
             read_image = images[0];
             if(!images[0] || !read_image) {
                 delete info;
                 if(remove(target.c_str()) != 0 ) {
-//                    clean_up(data, data_length, fd);
+                    if(images)
+                        delete [] images;
                     return EXIT_FAILURE;
                 }
             }
             int i;
             for(i = 0; i<img->data_length; i++) {
                 if(img->data[i] != read_image->data[i]) {
-//                    clean_up(data, data_length, fd);
-//                    delete [] read;
+                    if(images)
+                        delete [] images;
                     return EXIT_FAILURE;
                 }
             }
-//            clean_up(data, data_length, fd);
-//            delete [] read_image->read;
+            if(images)
+                delete [] images;
             if(remove(target.c_str()) != 0 )
                 return EXIT_FAILURE;
             return EXIT_SUCCESS;
         }
         delete info;
-//        clean_up(data, data_length, fd);
         if(remove(target.c_str()) != 0 )
             return EXIT_FAILURE;
         return EXIT_FAILURE;
     }
     else {
        delete info;
-//        clean_up(data, data_length, fd);
         if(remove(target.c_str()) != 0 )
             return EXIT_FAILURE;
         return EXIT_FAILURE;

File tests/write_image_mp4/main.cc

 #include <sys/stat.h>
 
 using namespace TagInfo;
-//using namespace std;
 
-void clean_up(char* map, int size, int fd) {
-    if(munmap(map, size) == -1) {
-        perror("Error un-mmapping the file");
-    }
-    if(fd != 0)
-        close(fd);
-}
 
 int main( void ) {
     Info * info;
     std::ofstream  dst(target.c_str());
     dst << src.rdbuf();
     
-    char* data;
-    int data_length;
-    ImageFileType image_file_type = IMAGE_FILE_TYPE_JPEG;
+    Image * img = new Image();
+    img->image_file_type = IMAGE_FILE_TYPE_JPEG;
+    img->image_type      = IMAGE_TYPE_OTHER;
     
     struct stat filestatus;
     stat( image.c_str(), &filestatus );
     //cout << filestatus.st_size << " bytes\n";
-    data_length = filestatus.st_size;
+    img->data_length = filestatus.st_size;
     int fd;
     
     fd = open(image.c_str(), O_RDONLY);
         perror("Error opening file for reading");
         EXIT_FAILURE;
     }
-    data = (char*)mmap(0, data_length, PROT_READ, MAP_SHARED, fd, 0);
-    if(data == MAP_FAILED) {
+    
+    img->data = (char*)mmap(0, img->data_length, PROT_READ, MAP_SHARED, fd, 0);
+    if(img->data == MAP_FAILED) {
         close(fd);
         perror("Error mmapping the file");
         EXIT_FAILURE;
     
     info = Info::create_tag_info(target);
     if(info) {
-        if(!info->set_image(data, data_length, image_file_type)) {
-            clean_up(data, data_length, fd);
-            delete info;
-            return EXIT_FAILURE;
-        }
+        Image ** imgs = new Image*[1];
+        imgs[0] = img;
+        info->set_images((const Image **)imgs, 1);
+        if(imgs)
+            delete [] imgs;
         info->write();
     }
     delete info;
     info = NULL;
     
     info = Info::create_tag_info(target);
-    char* read;
-    int read_length;
-    ImageFileType read_type;
+    Image * read_image;
     if(info) {
         if(info->read()) {
-            if(!info->get_image(read, read_length, read_type)) {
+            int len = 0;
+            Image ** images = info->get_images(len);
+            if(!images) {
                 delete info;
-                if(!read || remove(target.c_str()) != 0 ) {
-                    clean_up(data, data_length, fd);
+                if(remove(target.c_str()) != 0 ) {
+                    return EXIT_FAILURE;
+                }
+                return EXIT_FAILURE;
+            }
+            read_image = images[0];
+            if(!images[0] || !read_image) {
+                delete info;
+                if(remove(target.c_str()) != 0 ) {
+                    if(images)
+                        delete [] images;
                     return EXIT_FAILURE;
                 }
             }
             int i;
-            for(i = 0; i<data_length; i++) {
-                if(!read || data[i] != read[i]) {
-                    clean_up(data, data_length, fd);
-                    delete [] read;
+            for(i = 0; i<img->data_length; i++) {
+                if(img->data[i] != read_image->data[i]) {
+                    if(images)
+                        delete [] images;
                     return EXIT_FAILURE;
                 }
             }
-            clean_up(data, data_length, fd);
-            delete [] read;
+            if(images)
+                delete [] images;
             if(remove(target.c_str()) != 0 )
                 return EXIT_FAILURE;
             return EXIT_SUCCESS;
         }
         delete info;
-        clean_up(data, data_length, fd);
         if(remove(target.c_str()) != 0 )
             return EXIT_FAILURE;
         return EXIT_FAILURE;
     }
     else {
        delete info;
-        clean_up(data, data_length, fd);
         if(remove(target.c_str()) != 0 )
             return EXIT_FAILURE;
         return EXIT_FAILURE;
     }
     return EXIT_FAILURE;
 }
-

File tests/write_image_mpc/main.cc

 #include <sys/stat.h>
 
 using namespace TagInfo;
-//using namespace std;
 
-void clean_up(char* map, int size, int fd) {
-    if(munmap(map, size) == -1) {
-        perror("Error un-mmapping the file");
-    }
-    if(fd != 0)
-        close(fd);
-}
 
 int main( void ) {
     Info * info;
     std::ofstream  dst(target.c_str());
     dst << src.rdbuf();
     
-    char* data;
-    int data_length;
-    ImageFileType image_file_type = IMAGE_FILE_TYPE_JPEG;
-    
+
+    Image * img = new Image();
+    img->image_file_type = IMAGE_FILE_TYPE_JPEG;
+    img->image_type      = IMAGE_TYPE_OTHER;
+
     struct stat filestatus;
     stat( image.c_str(), &filestatus );
     //cout << filestatus.st_size << " bytes\n";
-    data_length = filestatus.st_size;
+    img->data_length = filestatus.st_size;
     int fd;
-    
     fd = open(image.c_str(), O_RDONLY);
     if (fd == -1) {
         perror("Error opening file for reading");
         EXIT_FAILURE;
     }
-    data = (char*)mmap(0, data_length, PROT_READ, MAP_SHARED, fd, 0);
-    if(data == MAP_FAILED) {
+    
+    img->data = (char*)mmap(0, img->data_length, PROT_READ, MAP_SHARED, fd, 0);
+    if(img->data == MAP_FAILED) {
         close(fd);
         perror("Error mmapping the file");
         EXIT_FAILURE;
     
     info = Info::create_tag_info(target);
     if(info) {
-        if(!info->set_image(data, data_length, image_file_type)) {
-            clean_up(data, data_length, fd);
-            delete info;
-            return EXIT_FAILURE;
-        }
+        Image ** imgs = new Image*[1];
+        imgs[0] = img;
+        info->set_images((const Image **)imgs, 1);
         info->write();
     }
     delete info;
     info = NULL;
     
     info = Info::create_tag_info(target);
-    char* read;
-    int read_length;
-    ImageFileType read_type;
+    Image * read_image = NULL;
+    
     if(info) {
         if(info->read()) {
-            if(!info->get_image(read, read_length, read_type)) {
+            int len = 0;
+            Image ** images = info->get_images(len);
+            if(!images) {
+                delete info;
+                if(remove(target.c_str()) != 0 ) {
+                    return EXIT_FAILURE;
+                }
+                return EXIT_FAILURE;
+            }
+            read_image = images[0];
+            if(!images[0] || !read_image) {
                 delete info;
-                if(!read || remove(target.c_str()) != 0 ) {
-                    clean_up(data, data_length, fd);
+                if(remove(target.c_str()) != 0 ) {
+                    if(img)
+                        delete img;
                     return EXIT_FAILURE;
                 }
+                return EXIT_FAILURE;
             }
             int i;
-            for(i = 0; i<data_length; i++) {
-                if(!read || data[i] != read[i]) {
-                    clean_up(data, data_length, fd);
-                    delete [] read;
+            for(i = 0; i<img->data_length; i++) {
+                if(img->data[i] != read_image->data[i]) {
+                    if(images)
+                        delete [] images;
+                    if(read_image)
+                        delete read_image;
                     return EXIT_FAILURE;
                 }
             }
-            clean_up(data, data_length, fd);
-            delete [] read;
+            if(images)
+                delete [] images;
             if(remove(target.c_str()) != 0 )
                 return EXIT_FAILURE;
             return EXIT_SUCCESS;
         }
         delete info;
-        clean_up(data, data_length, fd);
         if(remove(target.c_str()) != 0 )
             return EXIT_FAILURE;
         return EXIT_FAILURE;
     }
     else {
        delete info;
-        clean_up(data, data_length, fd);
         if(remove(target.c_str()) != 0 )
             return EXIT_FAILURE;
         return EXIT_FAILURE;

File tests/write_image_ogg/main.cc

 #include <sys/stat.h>
 
 using namespace TagInfo;
-//using namespace std;
 
-void clean_up(char* map, int size, int fd) {
-    if(munmap(map, size) == -1) {
-        perror("Error un-mmapping the file");
-    }
-    if(fd != 0)
-        close(fd);
-}
 
 int main( void ) {
     Info * info;
     img->image_file_type = IMAGE_FILE_TYPE_JPEG;
     img->image_type      = IMAGE_TYPE_OTHER;
 
-//    char* data;
-//    int data_length;
-//    ImageFileType image_file_type = IMAGE_FILE_TYPE_JPEG;
-    
     struct stat filestatus;
     stat( image.c_str(), &filestatus );
     //cout << filestatus.st_size << " bytes\n";
         Image ** imgs = new Image*[1];
         imgs[0] = img;
         info->set_images((const Image **)imgs, 1);
-//        if(!info->set_image(data, data_length, image_file_type)) {
-//            clean_up(data, data_length, fd);
-//            delete info;
-//            return EXIT_FAILURE;
-//        }
         info->write();
     }
     delete info;
     info = NULL;
     
     info = Info::create_tag_info(target);
-    Image * read_image;
+    Image * read_image = NULL;
     
     if(info) {
         if(info->read()) {
             int len = 0;
             Image ** images = info->get_images(len);
             if(!images) {
-//            if(!info->get_image(read, read_length, read_type)) {
                 delete info;
                 if(remove(target.c_str()) != 0 ) {
-//                    clean_up(data, data_length, fd);
                     return EXIT_FAILURE;
                 }
+                return EXIT_FAILURE;
             }
             read_image = images[0];
             if(!images[0] || !read_image) {
                 delete info;
                 if(remove(target.c_str()) != 0 ) {
-//                    clean_up(data, data_length, fd);
+                    if(img)
+                        delete img;
                     return EXIT_FAILURE;
                 }
             }
             int i;
             for(i = 0; i<img->data_length; i++) {
                 if(img->data[i] != read_image->data[i]) {
-//                    clean_up(data, data_length, fd);
-//                    delete [] read;
+                    if(images)
+                        delete [] images;
+                    if(read_image)
+                        delete read_image;
                     return EXIT_FAILURE;
                 }
             }
-//            clean_up(data, data_length, fd);
-//            delete [] read;
+            if(images)
+                delete [] images;
             if(remove(target.c_str()) != 0 )
                 return EXIT_FAILURE;
             return EXIT_SUCCESS;
         }
         delete info;
-//        clean_up(data, data_length, fd);
         if(remove(target.c_str()) != 0 )
             return EXIT_FAILURE;
         return EXIT_FAILURE;
     }
     else {
        delete info;
-//        clean_up(data, data_length, fd);
         if(remove(target.c_str()) != 0 )
             return EXIT_FAILURE;
         return EXIT_FAILURE;

File tests/write_image_speex/main.cc

 #include <sys/stat.h>
 
 using namespace TagInfo;
-//using namespace std;
 
-void clean_up(char* map, int size, int fd) {
-    if(munmap(map, size) == -1) {
-        perror("Error un-mmapping the file");
-    }
-    if(fd != 0)
-        close(fd);
-}
 
 int main( void ) {
     Info * info;