musikr: initial flac pic support
Probably broken
This commit is contained in:
parent
61069bd4fe
commit
3dfcf0f67a
8 changed files with 202 additions and 8 deletions
15
musikr/src/main/jni/shim/picture_shim.cpp
Normal file
15
musikr/src/main/jni/shim/picture_shim.cpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include "picture_shim.hpp"
|
||||
|
||||
namespace taglib_shim {
|
||||
std::unique_ptr<TagLib::String> Picture_mimeType(const TagLib::FLAC::Picture& picture) {
|
||||
return std::make_unique<TagLib::String>(picture.mimeType());
|
||||
}
|
||||
|
||||
std::unique_ptr<TagLib::String> Picture_description(const TagLib::FLAC::Picture& picture) {
|
||||
return std::make_unique<TagLib::String>(picture.description());
|
||||
}
|
||||
|
||||
std::unique_ptr<TagLib::ByteVector> Picture_data(const TagLib::FLAC::Picture& picture) {
|
||||
return std::make_unique<TagLib::ByteVector>(picture.data());
|
||||
}
|
||||
}
|
12
musikr/src/main/jni/shim/picture_shim.hpp
Normal file
12
musikr/src/main/jni/shim/picture_shim.hpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "taglib/flacpicture.h"
|
||||
#include "taglib/tstring.h"
|
||||
#include "taglib/tbytevector.h"
|
||||
#include <memory>
|
||||
|
||||
namespace taglib_shim {
|
||||
std::unique_ptr<TagLib::String> Picture_mimeType(const TagLib::FLAC::Picture& picture);
|
||||
std::unique_ptr<TagLib::String> Picture_description(const TagLib::FLAC::Picture& picture);
|
||||
std::unique_ptr<TagLib::ByteVector> Picture_data(const TagLib::FLAC::Picture& picture);
|
||||
}
|
|
@ -33,4 +33,41 @@ namespace taglib_shim
|
|||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<std::vector<PictureRef>> FLACFile_pictureList_to_vector(TagLib::FLAC::File &file)
|
||||
{
|
||||
std::unique_ptr<std::vector<PictureRef>> result = std::make_unique<std::vector<PictureRef>>();
|
||||
const auto pictures = file.pictureList();
|
||||
for (const auto &picture : pictures)
|
||||
{
|
||||
result->push_back(PictureRef(picture));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<std::vector<PictureRef>> XiphComment_pictureList_to_vector(TagLib::Ogg::XiphComment &comment)
|
||||
{
|
||||
std::unique_ptr<std::vector<PictureRef>> result = std::make_unique<std::vector<PictureRef>>();
|
||||
const auto pictures = comment.pictureList();
|
||||
for (const auto &picture : pictures)
|
||||
{
|
||||
result->push_back(PictureRef(picture));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
rust::String String_to_string(const TagLib::String &str)
|
||||
{
|
||||
return rust::String(str.to8Bit());
|
||||
}
|
||||
|
||||
std::unique_ptr<std::vector<uint8_t>> ByteVector_to_bytes(const TagLib::ByteVector &data)
|
||||
{
|
||||
auto result = std::make_unique<std::vector<uint8_t>>();
|
||||
result->reserve(data.size());
|
||||
for (size_t i = 0; i < data.size(); i++)
|
||||
{
|
||||
result->push_back(static_cast<uint8_t>(data[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,14 @@
|
|||
#include "taglib/xiphcomment.h"
|
||||
#include "taglib/tstring.h"
|
||||
#include "taglib/tstringlist.h"
|
||||
#include "taglib/flacpicture.h"
|
||||
#include "taglib/flacfile.h"
|
||||
#include "taglib/tbytevector.h"
|
||||
#include <memory>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "rust/cxx.h"
|
||||
|
||||
namespace taglib_shim
|
||||
{
|
||||
|
@ -21,6 +27,17 @@ namespace taglib_shim
|
|||
TagLib::StringList value_;
|
||||
};
|
||||
|
||||
struct PictureRef {
|
||||
PictureRef(const TagLib::FLAC::Picture* picture) : picture_(picture) {}
|
||||
const TagLib::FLAC::Picture* get() const { return picture_; }
|
||||
private:
|
||||
const TagLib::FLAC::Picture* picture_;
|
||||
};
|
||||
|
||||
std::unique_ptr<std::vector<Property>> SimplePropertyMap_to_vector(const TagLib::SimplePropertyMap &map);
|
||||
std::unique_ptr<std::vector<TagLib::String>> StringList_to_vector(const TagLib::StringList &list);
|
||||
std::unique_ptr<std::vector<PictureRef>> FLACFile_pictureList_to_vector(TagLib::FLAC::File &file);
|
||||
std::unique_ptr<std::vector<PictureRef>> XiphComment_pictureList_to_vector(TagLib::Ogg::XiphComment &comment);
|
||||
rust::String String_to_string(const TagLib::String &str);
|
||||
std::unique_ptr<std::vector<uint8_t>> ByteVector_to_bytes(const TagLib::ByteVector &data);
|
||||
}
|
|
@ -25,9 +25,12 @@ mod bridge_impl {
|
|||
include!("taglib/vorbisfile.h");
|
||||
include!("taglib/xiphcomment.h");
|
||||
include!("taglib/tiostream.h");
|
||||
include!("taglib/flacpicture.h");
|
||||
include!("taglib/tbytevector.h");
|
||||
include!("shim/iostream_shim.hpp");
|
||||
include!("shim/file_shim.hpp");
|
||||
include!("shim/tk_shim.hpp");
|
||||
include!("shim/picture_shim.hpp");
|
||||
|
||||
#[namespace = "TagLib"]
|
||||
#[cxx_name = "IOStream"]
|
||||
|
@ -64,6 +67,28 @@ mod bridge_impl {
|
|||
#[cxx_name = "channels"]
|
||||
fn channels(self: Pin<&CppAudioProperties>) -> i32;
|
||||
|
||||
#[namespace = "TagLib::FLAC"]
|
||||
#[cxx_name = "Picture"]
|
||||
type CPPFLACPicture;
|
||||
#[namespace = "taglib_shim"]
|
||||
fn Picture_mimeType(picture: &CPPFLACPicture) -> UniquePtr<CPPString>;
|
||||
#[namespace = "taglib_shim"]
|
||||
fn Picture_description(picture: &CPPFLACPicture) -> UniquePtr<CPPString>;
|
||||
#[cxx_name = "width"]
|
||||
fn width(self: Pin<&CPPFLACPicture>) -> i32;
|
||||
#[cxx_name = "height"]
|
||||
fn height(self: Pin<&CPPFLACPicture>) -> i32;
|
||||
#[cxx_name = "colorDepth"]
|
||||
fn colorDepth(self: Pin<&CPPFLACPicture>) -> i32;
|
||||
#[cxx_name = "numColors"]
|
||||
fn numColors(self: Pin<&CPPFLACPicture>) -> i32;
|
||||
#[namespace = "taglib_shim"]
|
||||
fn Picture_data(picture: &CPPFLACPicture) -> UniquePtr<CPPByteVector>;
|
||||
|
||||
#[namespace = "TagLib"]
|
||||
#[cxx_name = "ByteVector"]
|
||||
type CPPByteVector;
|
||||
|
||||
#[namespace = "TagLib::Ogg"]
|
||||
#[cxx_name = "XiphComment"]
|
||||
type CPPXiphComment;
|
||||
|
@ -148,6 +173,20 @@ mod bridge_impl {
|
|||
type CPPStringList;
|
||||
#[namespace = "taglib_shim"]
|
||||
fn StringList_to_vector(string_list: Pin<&CPPStringList>) -> UniquePtr<CxxVector<CPPString>>;
|
||||
|
||||
#[namespace = "taglib_shim"]
|
||||
type PictureRef;
|
||||
fn get(self: &PictureRef) -> *const CPPFLACPicture;
|
||||
|
||||
#[namespace = "taglib_shim"]
|
||||
fn FLACFile_pictureList_to_vector(file: Pin<&mut CPPFLACFile>) -> UniquePtr<CxxVector<PictureRef>>;
|
||||
#[namespace = "taglib_shim"]
|
||||
fn XiphComment_pictureList_to_vector(comment: Pin<&mut CPPXiphComment>) -> UniquePtr<CxxVector<PictureRef>>;
|
||||
|
||||
#[namespace = "taglib_shim"]
|
||||
fn String_to_string(str: &CPPString) -> String;
|
||||
#[namespace = "taglib_shim"]
|
||||
fn ByteVector_to_bytes(data: &CPPByteVector) -> UniquePtr<CxxVector<u8>>;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
pub use super::bridge::CPPFLACFile;
|
||||
pub use super::bridge::CPPFLACPicture;
|
||||
pub use super::xiph::XiphComment;
|
||||
use super::bridge::{FLACFile_pictureList_to_vector, String_to_string, ByteVector_to_bytes, Picture_mimeType, Picture_description, Picture_data};
|
||||
use std::pin::Pin;
|
||||
|
||||
pub struct FLACFile<'a> {
|
||||
|
@ -25,9 +27,63 @@ impl<'a> FLACFile<'a> {
|
|||
let tag_ref = unsafe {
|
||||
// SAFETY: This pointer is a valid type, and can only used and accessed
|
||||
// via this function and thus cannot be mutated, satisfying the aliasing rules.
|
||||
tag.as_ref()
|
||||
tag.as_mut()
|
||||
};
|
||||
let tag_pin = tag_ref.map(|tag| unsafe { Pin::new_unchecked(tag) });
|
||||
tag_pin.map(|tag| XiphComment::new(tag))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn picture_list(&mut self) -> Vec<Picture<'a>> {
|
||||
let pictures = FLACFile_pictureList_to_vector(self.this.as_mut());
|
||||
let mut result = Vec::new();
|
||||
for picture_ref in pictures.iter() {
|
||||
let picture_ptr = picture_ref.get();
|
||||
let picture_ref = unsafe {
|
||||
// SAFETY: This pointer is a valid type, and can only used and accessed
|
||||
// via this function and thus cannot be mutated, satisfying the aliasing rules.
|
||||
picture_ptr.as_ref().unwrap()
|
||||
};
|
||||
let picture_pin = unsafe { Pin::new_unchecked(picture_ref) };
|
||||
result.push(Picture::new(picture_pin));
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Picture<'a> {
|
||||
this: Pin<&'a CPPFLACPicture>
|
||||
}
|
||||
|
||||
impl<'a> Picture<'a> {
|
||||
pub(super) fn new(this: Pin<&'a CPPFLACPicture>) -> Self {
|
||||
Self { this }
|
||||
}
|
||||
|
||||
pub fn mime_type(&self) -> String {
|
||||
String_to_string(Picture_mimeType(self.this.get_ref()).as_ref().unwrap())
|
||||
}
|
||||
|
||||
pub fn description(&self) -> String {
|
||||
String_to_string(Picture_description(self.this.get_ref()).as_ref().unwrap())
|
||||
}
|
||||
|
||||
pub fn width(&self) -> i32 {
|
||||
self.this.width()
|
||||
}
|
||||
|
||||
pub fn height(&self) -> i32 {
|
||||
self.this.height()
|
||||
}
|
||||
|
||||
pub fn color_depth(&self) -> i32 {
|
||||
self.this.colorDepth()
|
||||
}
|
||||
|
||||
pub fn num_colors(&self) -> i32 {
|
||||
self.this.numColors()
|
||||
}
|
||||
|
||||
pub fn data(&self) -> Vec<u8> {
|
||||
ByteVector_to_bytes(Picture_data(self.this.get_ref()).as_ref().unwrap()).iter().map(|b| *b).collect()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ impl<'a> VorbisFile<'a> {
|
|||
let tag_ref = unsafe {
|
||||
// SAFETY: This pointer is a valid type, and can only used and accessed
|
||||
// via this function and thus cannot be mutated, satisfying the aliasing rules.
|
||||
tag.as_ref()
|
||||
tag.as_mut()
|
||||
};
|
||||
let tag_pin = tag_ref.map(|tag| unsafe { Pin::new_unchecked(tag) });
|
||||
tag_pin.map(|tag| XiphComment::new(tag))
|
||||
|
@ -53,7 +53,7 @@ impl <'a> OpusFile<'a> {
|
|||
let tag_ref = unsafe {
|
||||
// SAFETY: This pointer is a valid type, and can only used and accessed
|
||||
// via this function and thus cannot be mutated, satisfying the aliasing rules.
|
||||
tag.as_ref()
|
||||
tag.as_mut()
|
||||
};
|
||||
let tag_pin = tag_ref.map(|tag| unsafe { Pin::new_unchecked(tag) });
|
||||
tag_pin.map(|tag| XiphComment::new(tag))
|
||||
|
|
|
@ -1,19 +1,37 @@
|
|||
pub use super::bridge::CPPXiphComment;
|
||||
pub use super::flac::Picture;
|
||||
use super::bridge::XiphComment_pictureList_to_vector;
|
||||
use super::tk::SimplePropertyMap;
|
||||
use std::pin::Pin;
|
||||
|
||||
pub struct XiphComment<'a> {
|
||||
this: Pin<&'a CPPXiphComment>
|
||||
this: Pin<&'a mut CPPXiphComment>
|
||||
}
|
||||
|
||||
impl<'a> XiphComment<'a> {
|
||||
pub(super) fn new(this: Pin<&'a CPPXiphComment>) -> Self {
|
||||
pub(super) fn new(this: Pin<&'a mut CPPXiphComment>) -> Self {
|
||||
Self { this }
|
||||
}
|
||||
|
||||
pub fn field_list_map(&self) -> SimplePropertyMap<'a> {
|
||||
let map = self.this.fieldListMap();
|
||||
pub fn field_list_map(&'a self) -> SimplePropertyMap<'a> {
|
||||
let map = self.this.as_ref().fieldListMap();
|
||||
let map_pin = unsafe { Pin::new_unchecked(map) };
|
||||
SimplePropertyMap::new(map_pin)
|
||||
}
|
||||
|
||||
pub fn picture_list(&mut self) -> Vec<Picture<'a>> {
|
||||
let pictures = XiphComment_pictureList_to_vector(self.this.as_mut());
|
||||
let mut result = Vec::new();
|
||||
for picture_ref in pictures.iter() {
|
||||
let picture_ptr = picture_ref.get();
|
||||
let picture_ref = unsafe {
|
||||
// SAFETY: This pointer is a valid type, and can only used and accessed
|
||||
// via this function and thus cannot be mutated, satisfying the aliasing rules.
|
||||
picture_ptr.as_ref().unwrap()
|
||||
};
|
||||
let picture_pin = unsafe { Pin::new_unchecked(picture_ref) };
|
||||
result.push(Picture::new(picture_pin));
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue