#include #include static PyObject *flac_error; static PyObject * flac_pictures(char *fn) { FLAC__Metadata_Chain *chain; FLAC__Metadata_Iterator *iterator; FLAC__StreamMetadata *block; PyObject *description, *tuple, *list; chain = FLAC__metadata_chain_new(); if (chain == NULL) { return PyErr_NoMemory(); } if(!FLAC__metadata_chain_read(chain, fn)) { PyObject *s = PyString_FromFormat("metadata_chain_read (%d)", FLAC__metadata_chain_status(chain)); if (s != NULL) { PyErr_SetObject(flac_error, s); } return NULL; } iterator = FLAC__metadata_iterator_new(); if (iterator == NULL) { return PyErr_NoMemory(); } FLAC__metadata_iterator_init(iterator, chain); list = PyList_New(0); if (list == NULL) { return NULL; } do { /* This can fail, but the documentation doesn't say how, why, * or how to react. metaflac/operations.c just prints a * useless error message and keeps going. */ block = FLAC__metadata_iterator_get_block(iterator); if (block == NULL) { PyErr_SetString(flac_error, "metadata_iterator_get_block returned NULL"); return NULL; } if (block->type != FLAC__METADATA_TYPE_PICTURE) { continue; } description = PyUnicode_DecodeUTF8( (const char *)block->data.picture.description, strlen((const char *)block->data.picture.description), "strict"); if (description == NULL) { return NULL; } tuple = Py_BuildValue("(isOiiiis#)", block->data.picture.type, block->data.picture.mime_type, description, block->data.picture.width, block->data.picture.height, block->data.picture.depth, block->data.picture.colors, block->data.picture.data, block->data.picture.data_length); if (tuple == NULL) { return NULL; } if (PyList_Append(list, tuple) == -1) { return NULL; } } while(FLAC__metadata_iterator_next(iterator)); FLAC__metadata_iterator_delete(iterator); FLAC__metadata_chain_delete(chain); return list; } static PyObject * get_pictures(PyObject *self, PyObject *args) { char *fn; if (!PyArg_ParseTuple(args, "s", &fn)) { return NULL; } return flac_pictures(fn); } static PyMethodDef methods[] = { {"get_pictures", get_pictures, METH_VARARGS, "document me"}, {NULL, NULL, 0, NULL} }; static void export_constants(PyObject *m) { PyObject *n; #define foo(x) \ n = PyInt_FromLong(FLAC__STREAM_METADATA_ ## x); \ if (n == NULL || PyModule_AddObject(m, #x, n) == -1) return; foo(PICTURE_TYPE_OTHER); foo(PICTURE_TYPE_FILE_ICON_STANDARD); foo(PICTURE_TYPE_FILE_ICON); foo(PICTURE_TYPE_FRONT_COVER); foo(PICTURE_TYPE_BACK_COVER); foo(PICTURE_TYPE_LEAFLET_PAGE); foo(PICTURE_TYPE_MEDIA); foo(PICTURE_TYPE_LEAD_ARTIST); foo(PICTURE_TYPE_ARTIST); foo(PICTURE_TYPE_CONDUCTOR); foo(PICTURE_TYPE_BAND); foo(PICTURE_TYPE_COMPOSER); foo(PICTURE_TYPE_LYRICIST); foo(PICTURE_TYPE_RECORDING_LOCATION); foo(PICTURE_TYPE_DURING_RECORDING); foo(PICTURE_TYPE_DURING_PERFORMANCE); foo(PICTURE_TYPE_VIDEO_SCREEN_CAPTURE); foo(PICTURE_TYPE_FISH); foo(PICTURE_TYPE_ILLUSTRATION); foo(PICTURE_TYPE_BAND_LOGOTYPE); foo(PICTURE_TYPE_PUBLISHER_LOGOTYPE); foo(PICTURE_TYPE_UNDEFINED); #undef foo } PyMODINIT_FUNC initflac(void) { PyObject *m = Py_InitModule("flac", methods); if (m == NULL) { return; } flac_error = PyErr_NewException("flac_archive.flac.error", NULL, NULL); if (flac_error == NULL) { return; } PyModule_AddObject(m, "error", flac_error); export_constants(m); }