From 2001db8c18bcd949f189f324f297a0204515be07 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Sun, 16 Jul 2006 17:49:15 +0000 Subject: Remove hosted libid3tag & libmad git-svn-id: https://svn.musicpd.org/mpd/trunk@4369 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- src/libid3tag/tag.c | 909 ---------------------------------------------------- 1 file changed, 909 deletions(-) (limited to 'src/libid3tag/tag.c') diff --git a/src/libid3tag/tag.c b/src/libid3tag/tag.c index be4e8e777..e69de29bb 100644 --- a/src/libid3tag/tag.c +++ b/src/libid3tag/tag.c @@ -1,909 +0,0 @@ -/* - * libid3tag - ID3 tag manipulation library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: tag.c,v 1.20 2004/02/17 02:04:10 rob Exp $ - */ - -# ifdef HAVE_CONFIG_H -# include "config.h" -# endif - -# include "global.h" - -# include -# include - -# ifdef HAVE_ASSERT_H -# include -# endif - -# include "id3tag.h" -# include "tag.h" -# include "frame.h" -# include "compat.h" -# include "parse.h" -# include "render.h" -# include "latin1.h" -# include "ucs4.h" -# include "genre.h" -# include "crc.h" -# include "field.h" -# include "util.h" - -/* - * NAME: tag->new() - * DESCRIPTION: allocate and return a new, empty tag - */ -struct id3_tag *id3_tag_new(void) -{ - struct id3_tag *tag; - - tag = malloc(sizeof(*tag)); - if (tag) { - tag->refcount = 0; - tag->version = ID3_TAG_VERSION; - tag->flags = 0; - tag->extendedflags = 0; - tag->restrictions = 0; - tag->options = /* ID3_TAG_OPTION_UNSYNCHRONISATION | */ - ID3_TAG_OPTION_COMPRESSION | ID3_TAG_OPTION_CRC; - tag->nframes = 0; - tag->frames = 0; - tag->paddedsize = 0; - } - - return tag; -} - -/* - * NAME: tag->delete() - * DESCRIPTION: destroy a tag and deallocate all associated memory - */ -void id3_tag_delete(struct id3_tag *tag) -{ - assert(tag); - - if (tag->refcount == 0) { - id3_tag_clearframes(tag); - - if (tag->frames) - free(tag->frames); - - free(tag); - } -} - -/* - * NAME: tag->addref() - * DESCRIPTION: add an external reference to a tag - */ -void id3_tag_addref(struct id3_tag *tag) -{ - assert(tag); - - ++tag->refcount; -} - -/* - * NAME: tag->delref() - * DESCRIPTION: remove an external reference to a tag - */ -void id3_tag_delref(struct id3_tag *tag) -{ - assert(tag && tag->refcount > 0); - - --tag->refcount; -} - -/* - * NAME: tag->version() - * DESCRIPTION: return the tag's original ID3 version number - */ -unsigned int id3_tag_version(struct id3_tag const *tag) -{ - assert(tag); - - return tag->version; -} - -/* - * NAME: tag->options() - * DESCRIPTION: get or set tag options - */ -int id3_tag_options(struct id3_tag *tag, int mask, int values) -{ - assert(tag); - - if (mask) - tag->options = (tag->options & ~mask) | (values & mask); - - return tag->options; -} - -/* - * NAME: tag->setlength() - * DESCRIPTION: set the minimum rendered tag size - */ -void id3_tag_setlength(struct id3_tag *tag, id3_length_t length) -{ - assert(tag); - - tag->paddedsize = length; -} - -/* - * NAME: tag->clearframes() - * DESCRIPTION: detach and delete all frames associated with a tag - */ -void id3_tag_clearframes(struct id3_tag *tag) -{ - unsigned int i; - - assert(tag); - - for (i = 0; i < tag->nframes; ++i) { - id3_frame_delref(tag->frames[i]); - id3_frame_delete(tag->frames[i]); - } - - tag->nframes = 0; -} - -/* - * NAME: tag->attachframe() - * DESCRIPTION: attach a frame to a tag - */ -int id3_tag_attachframe(struct id3_tag *tag, struct id3_frame *frame) -{ - struct id3_frame **frames; - - assert(tag && frame); - - frames = realloc(tag->frames, (tag->nframes + 1) * sizeof(*frames)); - if (frames == 0) - return -1; - - tag->frames = frames; - tag->frames[tag->nframes++] = frame; - - id3_frame_addref(frame); - - return 0; -} - -/* - * NAME: tag->detachframe() - * DESCRIPTION: detach (but don't delete) a frame from a tag - */ -int id3_tag_detachframe(struct id3_tag *tag, struct id3_frame *frame) -{ - unsigned int i; - - assert(tag && frame); - - for (i = 0; i < tag->nframes; ++i) { - if (tag->frames[i] == frame) - break; - } - - if (i == tag->nframes) - return -1; - - --tag->nframes; - while (i++ < tag->nframes) - tag->frames[i - 1] = tag->frames[i]; - - id3_frame_delref(frame); - - return 0; -} - -/* - * NAME: tag->findframe() - * DESCRIPTION: find in a tag the nth (0-based) frame with the given frame ID - */ -struct id3_frame *id3_tag_findframe(struct id3_tag const *tag, - char const *id, unsigned int index) -{ - unsigned int len, i; - - assert(tag); - - if (id == 0 || *id == 0) - return (index < tag->nframes) ? tag->frames[index] : 0; - - len = strlen(id); - - if (len == 4) { - struct id3_compat const *compat; - - compat = id3_compat_lookup(id, len); - if (compat && compat->equiv && !compat->translate) { - id = compat->equiv; - len = strlen(id); - } - } - - for (i = 0; i < tag->nframes; ++i) { - if (strncmp(tag->frames[i]->id, id, len) == 0 && index-- == 0) - return tag->frames[i]; - } - - return 0; -} - -enum tagtype { - TAGTYPE_NONE = 0, - TAGTYPE_ID3V1, - TAGTYPE_ID3V2, - TAGTYPE_ID3V2_FOOTER -}; - -static -enum tagtype tagtype(id3_byte_t const *data, id3_length_t length) -{ - if (length >= 3 && - data[0] == 'T' && data[1] == 'A' && data[2] == 'G') - return TAGTYPE_ID3V1; - - if (length >= 10 && - ((data[0] == 'I' && data[1] == 'D' && data[2] == '3') || - (data[0] == '3' && data[1] == 'D' && data[2] == 'I')) && - data[3] < 0xff && data[4] < 0xff && - data[6] < 0x80 && data[7] < 0x80 && data[8] < 0x80 && data[9] < 0x80) - return data[0] == 'I' ? TAGTYPE_ID3V2 : TAGTYPE_ID3V2_FOOTER; - - return TAGTYPE_NONE; -} - -static -void parse_header(id3_byte_t const **ptr, - unsigned int *version, int *flags, id3_length_t *size) -{ - *ptr += 3; - - *version = id3_parse_uint(ptr, 2); - *flags = id3_parse_uint(ptr, 1); - *size = id3_parse_syncsafe(ptr, 4); -} - -/* - * NAME: tag->query() - * DESCRIPTION: if a tag begins at the given location, return its size - */ -signed long id3_tag_query(id3_byte_t const *data, id3_length_t length) -{ - unsigned int version; - int flags; - id3_length_t size; - - assert(data); - - switch (tagtype(data, length)) { - case TAGTYPE_ID3V1: - return 128; - - case TAGTYPE_ID3V2: - parse_header(&data, &version, &flags, &size); - - if (flags & ID3_TAG_FLAG_FOOTERPRESENT) - size += 10; - - return 10 + size; - - case TAGTYPE_ID3V2_FOOTER: - parse_header(&data, &version, &flags, &size); - return -size - 10; - - case TAGTYPE_NONE: - break; - } - - return 0; -} - -static -void trim(char *str) -{ - char *ptr; - - ptr = str + strlen(str); - while (ptr > str && ptr[-1] == ' ') - --ptr; - - *ptr = 0; -} - -static -int v1_attachstr(struct id3_tag *tag, char const *id, - char *text, unsigned long number) -{ - struct id3_frame *frame; - id3_ucs4_t ucs4[31]; - - if (text) { - trim(text); - if (*text == 0) - return 0; - } - - frame = id3_frame_new(id); - if (frame == 0) - return -1; - - if (id3_field_settextencoding(&frame->fields[0], - ID3_FIELD_TEXTENCODING_ISO_8859_1) == -1) - goto fail; - - if (text) - id3_latin1_decode(text, ucs4); - else - id3_ucs4_putnumber(ucs4, number); - - if (strcmp(id, ID3_FRAME_COMMENT) == 0) { - if (id3_field_setlanguage(&frame->fields[1], "XXX") == -1 || - id3_field_setstring(&frame->fields[2], id3_ucs4_empty) == -1 || - id3_field_setfullstring(&frame->fields[3], ucs4) == -1) - goto fail; - } - else { - id3_ucs4_t *ptr = ucs4; - - if (id3_field_setstrings(&frame->fields[1], 1, &ptr) == -1) - goto fail; - } - - if (id3_tag_attachframe(tag, frame) == -1) - goto fail; - - return 0; - - fail: - id3_frame_delete(frame); - return -1; -} - -static -struct id3_tag *v1_parse(id3_byte_t const *data) -{ - struct id3_tag *tag; - - tag = id3_tag_new(); - if (tag) { - char title[31], artist[31], album[31], year[5], comment[31]; - unsigned int genre, track; - - tag->version = 0x0100; - - tag->options |= ID3_TAG_OPTION_ID3V1; - tag->options &= ~ID3_TAG_OPTION_COMPRESSION; - - tag->restrictions = - ID3_TAG_RESTRICTION_TEXTENCODING_LATIN1_UTF8 | - ID3_TAG_RESTRICTION_TEXTSIZE_30_CHARS; - - title[30] = artist[30] = album[30] = year[4] = comment[30] = 0; - - memcpy(title, &data[3], 30); - memcpy(artist, &data[33], 30); - memcpy(album, &data[63], 30); - memcpy(year, &data[93], 4); - memcpy(comment, &data[97], 30); - - genre = data[127]; - - track = 0; - if (comment[28] == 0 && comment[29] != 0) { - track = comment[29]; - tag->version = 0x0101; - } - - /* populate tag frames */ - - if (v1_attachstr(tag, ID3_FRAME_TITLE, title, 0) == -1 || - v1_attachstr(tag, ID3_FRAME_ARTIST, artist, 0) == -1 || - v1_attachstr(tag, ID3_FRAME_ALBUM, album, 0) == -1 || - v1_attachstr(tag, ID3_FRAME_YEAR, year, 0) == -1 || - (track && v1_attachstr(tag, ID3_FRAME_TRACK, 0, track) == -1) || - (genre < 0xff && v1_attachstr(tag, ID3_FRAME_GENRE, 0, genre) == -1) || - v1_attachstr(tag, ID3_FRAME_COMMENT, comment, 0) == -1) { - id3_tag_delete(tag); - tag = 0; - } - } - - return tag; -} - -static -struct id3_tag *v2_parse(id3_byte_t const *ptr) -{ - struct id3_tag *tag; - id3_byte_t *mem = 0; - - tag = id3_tag_new(); - if (tag) { - id3_byte_t const *end; - id3_length_t size; - - parse_header(&ptr, &tag->version, &tag->flags, &size); - - tag->paddedsize = 10 + size; - - if ((tag->flags & ID3_TAG_FLAG_UNSYNCHRONISATION) && - ID3_TAG_VERSION_MAJOR(tag->version) < 4) { - mem = malloc(size); - if (mem == 0) - goto fail; - - memcpy(mem, ptr, size); - - size = id3_util_deunsynchronise(mem, size); - ptr = mem; - } - - end = ptr + size; - - if (tag->flags & ID3_TAG_FLAG_EXTENDEDHEADER) { - switch (ID3_TAG_VERSION_MAJOR(tag->version)) { - case 2: - goto fail; - - case 3: - { - id3_byte_t const *ehptr, *ehend; - id3_length_t ehsize; - - enum { - EH_FLAG_CRC = 0x8000 /* CRC data present */ - }; - - if (end - ptr < 4) - goto fail; - - ehsize = id3_parse_uint(&ptr, 4); - - if (ehsize > end - ptr) - goto fail; - - ehptr = ptr; - ehend = ptr + ehsize; - - ptr = ehend; - - if (ehend - ehptr >= 6) { - int ehflags; - id3_length_t padsize; - - ehflags = id3_parse_uint(&ehptr, 2); - padsize = id3_parse_uint(&ehptr, 4); - - if (padsize > end - ptr) - goto fail; - - end -= padsize; - - if (ehflags & EH_FLAG_CRC) { - unsigned long crc; - - if (ehend - ehptr < 4) - goto fail; - - crc = id3_parse_uint(&ehptr, 4); - - if (crc != id3_crc_compute(ptr, end - ptr)) - goto fail; - - tag->extendedflags |= ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT; - } - } - } - break; - - case 4: - { - id3_byte_t const *ehptr, *ehend; - id3_length_t ehsize; - unsigned int bytes; - - if (end - ptr < 4) - goto fail; - - ehptr = ptr; - ehsize = id3_parse_syncsafe(&ptr, 4); - - if (ehsize < 6 || ehsize > end - ehptr) - goto fail; - - ehend = ehptr + ehsize; - - bytes = id3_parse_uint(&ptr, 1); - - if (bytes < 1 || bytes > ehend - ptr) - goto fail; - - ehptr = ptr + bytes; - - /* verify extended header size */ - { - id3_byte_t const *flagsptr = ptr, *dataptr = ehptr; - unsigned int datalen; - int ehflags; - - while (bytes--) { - for (ehflags = id3_parse_uint(&flagsptr, 1); ehflags; - ehflags = (ehflags << 1) & 0xff) { - if (ehflags & 0x80) { - if (dataptr == ehend) - goto fail; - datalen = id3_parse_uint(&dataptr, 1); - if (datalen > 0x7f || datalen > ehend - dataptr) - goto fail; - dataptr += datalen; - } - } - } - } - - tag->extendedflags = id3_parse_uint(&ptr, 1); - - ptr = ehend; - - if (tag->extendedflags & ID3_TAG_EXTENDEDFLAG_TAGISANUPDATE) { - bytes = id3_parse_uint(&ehptr, 1); - ehptr += bytes; - } - - if (tag->extendedflags & ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT) { - unsigned long crc; - - bytes = id3_parse_uint(&ehptr, 1); - if (bytes < 5) - goto fail; - - crc = id3_parse_syncsafe(&ehptr, 5); - ehptr += bytes - 5; - - if (crc != id3_crc_compute(ptr, end - ptr)) - goto fail; - } - - if (tag->extendedflags & ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS) { - bytes = id3_parse_uint(&ehptr, 1); - if (bytes < 1) - goto fail; - - tag->restrictions = id3_parse_uint(&ehptr, 1); - ehptr += bytes - 1; - } - } - break; - } - } - - /* frames */ - - while (ptr < end) { - struct id3_frame *frame; - - if (*ptr == 0) - break; /* padding */ - - frame = id3_frame_parse(&ptr, end - ptr, tag->version); - if (frame == 0 || id3_tag_attachframe(tag, frame) == -1) - goto fail; - } - - if (ID3_TAG_VERSION_MAJOR(tag->version) < 4 && - id3_compat_fixup(tag) == -1) - goto fail; - } - - if (0) { - fail: - id3_tag_delete(tag); - tag = 0; - } - - if (mem) - free(mem); - - return tag; -} - -/* - * NAME: tag->parse() - * DESCRIPTION: parse a complete ID3 tag - */ -struct id3_tag *id3_tag_parse(id3_byte_t const *data, id3_length_t length) -{ - id3_byte_t const *ptr; - unsigned int version; - int flags; - id3_length_t size; - - assert(data); - - switch (tagtype(data, length)) { - case TAGTYPE_ID3V1: - return (length < 128) ? 0 : v1_parse(data); - - case TAGTYPE_ID3V2: - break; - - case TAGTYPE_ID3V2_FOOTER: - case TAGTYPE_NONE: - return 0; - } - - /* ID3v2.x */ - - ptr = data; - parse_header(&ptr, &version, &flags, &size); - - switch (ID3_TAG_VERSION_MAJOR(version)) { - case 4: - if (flags & ID3_TAG_FLAG_FOOTERPRESENT) - size += 10; - case 2: - case 3: - return (length < 10 + size) ? 0 : v2_parse(data); - } - - return 0; -} - -static -void v1_renderstr(struct id3_tag const *tag, char const *frameid, - id3_byte_t **buffer, id3_length_t length) -{ - struct id3_frame *frame; - id3_ucs4_t const *string; - - frame = id3_tag_findframe(tag, frameid, 0); - if (frame == 0) - string = id3_ucs4_empty; - else { - if (strcmp(frameid, ID3_FRAME_COMMENT) == 0) - string = id3_field_getfullstring(&frame->fields[3]); - else - string = id3_field_getstrings(&frame->fields[1], 0); - } - - id3_render_paddedstring(buffer, string, length); -} - -/* - * NAME: v1->render() - * DESCRIPTION: render an ID3v1 (or ID3v1.1) tag - */ -static -id3_length_t v1_render(struct id3_tag const *tag, id3_byte_t *buffer) -{ - id3_byte_t data[128], *ptr; - struct id3_frame *frame; - unsigned int i; - int genre = -1; - - ptr = data; - - id3_render_immediate(&ptr, "TAG", 3); - - v1_renderstr(tag, ID3_FRAME_TITLE, &ptr, 30); - v1_renderstr(tag, ID3_FRAME_ARTIST, &ptr, 30); - v1_renderstr(tag, ID3_FRAME_ALBUM, &ptr, 30); - v1_renderstr(tag, ID3_FRAME_YEAR, &ptr, 4); - v1_renderstr(tag, ID3_FRAME_COMMENT, &ptr, 30); - - /* ID3v1.1 track number */ - - frame = id3_tag_findframe(tag, ID3_FRAME_TRACK, 0); - if (frame) { - unsigned int track; - - track = id3_ucs4_getnumber(id3_field_getstrings(&frame->fields[1], 0)); - if (track > 0 && track <= 0xff) { - ptr[-2] = 0; - ptr[-1] = track; - } - } - - /* ID3v1 genre number */ - - frame = id3_tag_findframe(tag, ID3_FRAME_GENRE, 0); - if (frame) { - unsigned int nstrings; - - nstrings = id3_field_getnstrings(&frame->fields[1]); - - for (i = 0; i < nstrings; ++i) { - genre = id3_genre_number(id3_field_getstrings(&frame->fields[1], i)); - if (genre != -1) - break; - } - - if (i == nstrings && nstrings > 0) - genre = ID3_GENRE_OTHER; - } - - id3_render_int(&ptr, genre, 1); - - /* make sure the tag is not empty */ - - if (genre == -1) { - for (i = 3; i < 127; ++i) { - if (data[i] != ' ') - break; - } - - if (i == 127) - return 0; - } - - if (buffer) - memcpy(buffer, data, 128); - - return 128; -} - -/* - * NAME: tag->render() - * DESCRIPTION: render a complete ID3 tag - */ -id3_length_t id3_tag_render(struct id3_tag const *tag, id3_byte_t *buffer) -{ - id3_length_t size = 0; - id3_byte_t **ptr, - *header_ptr = 0, *tagsize_ptr = 0, *crc_ptr = 0, *frames_ptr = 0; - int flags, extendedflags; - unsigned int i; - - assert(tag); - - if (tag->options & ID3_TAG_OPTION_ID3V1) - return v1_render(tag, buffer); - - /* a tag must contain at least one (renderable) frame */ - - for (i = 0; i < tag->nframes; ++i) { - if (id3_frame_render(tag->frames[i], 0, 0) > 0) - break; - } - - if (i == tag->nframes) - return 0; - - ptr = buffer ? &buffer : 0; - - /* get flags */ - - flags = tag->flags & ID3_TAG_FLAG_KNOWNFLAGS; - extendedflags = tag->extendedflags & ID3_TAG_EXTENDEDFLAG_KNOWNFLAGS; - - extendedflags &= ~ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT; - if (tag->options & ID3_TAG_OPTION_CRC) - extendedflags |= ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT; - - extendedflags &= ~ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS; - if (tag->restrictions) - extendedflags |= ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS; - - flags &= ~ID3_TAG_FLAG_UNSYNCHRONISATION; - if (tag->options & ID3_TAG_OPTION_UNSYNCHRONISATION) - flags |= ID3_TAG_FLAG_UNSYNCHRONISATION; - - flags &= ~ID3_TAG_FLAG_EXTENDEDHEADER; - if (extendedflags) - flags |= ID3_TAG_FLAG_EXTENDEDHEADER; - - flags &= ~ID3_TAG_FLAG_FOOTERPRESENT; - if (tag->options & ID3_TAG_OPTION_APPENDEDTAG) - flags |= ID3_TAG_FLAG_FOOTERPRESENT; - - /* header */ - - if (ptr) - header_ptr = *ptr; - - size += id3_render_immediate(ptr, "ID3", 3); - size += id3_render_int(ptr, ID3_TAG_VERSION, 2); - size += id3_render_int(ptr, flags, 1); - - if (ptr) - tagsize_ptr = *ptr; - - size += id3_render_syncsafe(ptr, 0, 4); - - /* extended header */ - - if (flags & ID3_TAG_FLAG_EXTENDEDHEADER) { - id3_length_t ehsize = 0; - id3_byte_t *ehsize_ptr = 0; - - if (ptr) - ehsize_ptr = *ptr; - - ehsize += id3_render_syncsafe(ptr, 0, 4); - ehsize += id3_render_int(ptr, 1, 1); - ehsize += id3_render_int(ptr, extendedflags, 1); - - if (extendedflags & ID3_TAG_EXTENDEDFLAG_TAGISANUPDATE) - ehsize += id3_render_int(ptr, 0, 1); - - if (extendedflags & ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT) { - ehsize += id3_render_int(ptr, 5, 1); - - if (ptr) - crc_ptr = *ptr; - - ehsize += id3_render_syncsafe(ptr, 0, 5); - } - - if (extendedflags & ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS) { - ehsize += id3_render_int(ptr, 1, 1); - ehsize += id3_render_int(ptr, tag->restrictions, 1); - } - - if (ehsize_ptr) - id3_render_syncsafe(&ehsize_ptr, ehsize, 4); - - size += ehsize; - } - - /* frames */ - - if (ptr) - frames_ptr = *ptr; - - for (i = 0; i < tag->nframes; ++i) - size += id3_frame_render(tag->frames[i], ptr, tag->options); - - /* padding */ - - if (!(flags & ID3_TAG_FLAG_FOOTERPRESENT)) { - if (size < tag->paddedsize) - size += id3_render_padding(ptr, 0, tag->paddedsize - size); - else if (tag->options & ID3_TAG_OPTION_UNSYNCHRONISATION) { - if (ptr == 0) - size += 1; - else { - if ((*ptr)[-1] == 0xff) - size += id3_render_padding(ptr, 0, 1); - } - } - } - - /* patch tag size and CRC */ - - if (tagsize_ptr) - id3_render_syncsafe(&tagsize_ptr, size - 10, 4); - - if (crc_ptr) { - id3_render_syncsafe(&crc_ptr, - id3_crc_compute(frames_ptr, *ptr - frames_ptr), 5); - } - - /* footer */ - - if (flags & ID3_TAG_FLAG_FOOTERPRESENT) { - size += id3_render_immediate(ptr, "3DI", 3); - size += id3_render_binary(ptr, header_ptr + 3, 7); - } - - return size; -} -- cgit v1.2.3