summaryrefslogtreecommitdiff
path: root/plugins/liboggedit/oggedit_art.c
diff options
context:
space:
mode:
authorGravatar Ian Nartowicz <iann@crunchbang>2014-06-04 22:45:30 +0100
committerGravatar Ian Nartowicz <iann@crunchbang>2014-06-04 22:45:30 +0100
commit823a4064ebcd2662f8e480f99326ac75dd6404a7 (patch)
tree420f6df26d390479f5573acb4f922d62d458ae8c /plugins/liboggedit/oggedit_art.c
parent923bdcd04d441869dc0fc9350c5bfb856f6e5677 (diff)
Full release of oggedit
Diffstat (limited to 'plugins/liboggedit/oggedit_art.c')
-rw-r--r--plugins/liboggedit/oggedit_art.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/plugins/liboggedit/oggedit_art.c b/plugins/liboggedit/oggedit_art.c
new file mode 100644
index 00000000..44e1c015
--- /dev/null
+++ b/plugins/liboggedit/oggedit_art.c
@@ -0,0 +1,172 @@
+/*
+ This file is part of Deadbeef Player source code
+ http://deadbeef.sourceforge.net
+
+ DeaDBeeF Ogg Edit library album art functions
+
+ Copyright (C) 2014 Ian Nartowicz <deadbeef@nartowicz.co.uk>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <ogg/ogg.h>
+#include <deadbeef/deadbeef.h>
+#include "oggedit_internal.h"
+#include "oggedit.h"
+
+const char *oggedit_album_art_type(const int type)
+{
+ switch (type) {
+ case 1:
+ return "32x32 pixels file icon";
+ case 2:
+ return "other file icon";
+ case 3:
+ return "front cover";
+ case 4:
+ return "back cover";
+ case 5:
+ return "leaflet page";
+ case 6:
+ return "media";
+ case 7:
+ return "lead artist/lead performer/soloist";
+ case 8:
+ return "artist/performer";
+ case 9:
+ return "conductor";
+ case 10:
+ return "band/orchestra";
+ case 11:
+ return "composer";
+ case 12:
+ return "lyricist/text writer";
+ case 13:
+ return "recording location";
+ case 14:
+ return "during recording";
+ case 15:
+ return "during performance";
+ case 16:
+ return "movie/video screen capture";
+ case 17:
+ return "bright coloured fish";
+ case 18:
+ return "illustration";
+ case 19:
+ return "band/artist logotype";
+ case 20:
+ return "publisher/studio logotype";
+ default:
+ return "other";
+ }
+}
+
+static char *btoa(const unsigned char *binary, const size_t binary_length)
+{
+ const char b64[64] = {
+ 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
+ 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
+ '0','1','2','3','4','5','6','7','8','9','+','/'
+ };
+
+ char *ascii_base64 = malloc((binary_length-1)/3 * 4 + 5);
+ if (!ascii_base64)
+ return NULL;
+
+ char *p = ascii_base64;
+ const unsigned char *q = binary;
+ const unsigned char *binary_end = binary + binary_length;
+ while (q+2 < binary_end) {
+ uint32_t chunk = q[0]<<16 | q[1]<<8 | q[2];
+ p[3] = b64[chunk & 0x3f];
+ p[2] = b64[chunk>>6 & 0x3f];
+ p[1] = b64[chunk>>12 & 0x3f];
+ p[0] = b64[chunk>>18 & 0x3f];
+ p+=4, q+=3;
+ }
+
+ if (q < binary_end) {
+ uint16_t remainder = q[0]<<8 | (q+1 == binary_end ? '\0' : q[1]);
+ p[3] = '=';
+ p[2] = q+1 == binary_end ? '=' : b64[remainder<<2 & 0x3f];
+ p[1] = b64[remainder>>4 & 0x3f];
+ p[0] = b64[remainder>>10 & 0x3f];
+ p+=4;
+ }
+ *p = '\0';
+
+ return ascii_base64;
+}
+
+char *oggedit_album_art_tag(DB_FILE *fp, int *res)
+{
+ if (!fp) {
+ *res = OGGEDIT_FILE_NOT_OPEN;
+ return NULL;
+ }
+
+ const int64_t data_length = fp->vfs->getlength(fp);
+ if (data_length < 50 || data_length > 10000000) {
+ fp->vfs->close(fp);
+ *res = OGGEDIT_BAD_FILE_LENGTH;
+ return NULL;
+ }
+
+ char *data = malloc(data_length);
+ if (!data) {
+ fp->vfs->close(fp);
+ *res = OGGEDIT_ALLOCATION_FAILURE;
+ return NULL;
+ }
+
+ const size_t data_read = fp->vfs->read(data, 1, data_length, fp);
+ fp->vfs->close(fp);
+ if (data_read != data_length) {
+ free(data);
+ *res = OGGEDIT_CANT_READ_IMAGE_FILE;
+ return NULL;
+ }
+
+ oggpack_buffer opb;
+ oggpackB_writeinit(&opb);
+ oggpackB_write(&opb, 3, 32);
+ _oggpackB_string(&opb, memcmp(data, "\x89PNG\x0D\x0A\x1A\x0A", 8) ? "image/jpeg" : "image/png");
+ _oggpackB_string(&opb, "Album art added from DeaDBeeF");
+ oggpackB_write(&opb, 0, 32);
+ oggpackB_write(&opb, 0, 32);
+ oggpackB_write(&opb, 0, 32);
+ oggpackB_write(&opb, 0, 32);
+ oggpackB_write(&opb, data_length, 32);
+ _oggpack_chars(&opb, data, data_length);
+ free(data);
+ if (oggpack_writecheck(&opb)) {
+ *res = OGGEDIT_ALLOCATION_FAILURE;
+ return NULL;
+ }
+
+ char *tag = btoa(oggpackB_get_buffer(&opb), oggpackB_bytes(&opb));
+ oggpackB_writeclear(&opb);
+ return tag;
+}