diff options
-rw-r--r-- | apps/buffering.c | 29 | ||||
-rw-r--r-- | apps/metadata.h | 21 | ||||
-rw-r--r-- | apps/metadata/id3tags.c | 76 | ||||
-rw-r--r-- | apps/playback.c | 35 | ||||
-rw-r--r-- | apps/playback.h | 7 | ||||
-rw-r--r-- | apps/recorder/jpeg_load.c | 43 | ||||
-rw-r--r-- | apps/recorder/jpeg_load.h | 23 |
7 files changed, 213 insertions, 21 deletions
diff --git a/apps/buffering.c b/apps/buffering.c index 123c7bc85f..9c0ad138f7 100644 --- a/apps/buffering.c +++ b/apps/buffering.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include "albumart.h" | 52 | #include "albumart.h" |
53 | #include "jpeg_load.h" | 53 | #include "jpeg_load.h" |
54 | #include "bmp.h" | 54 | #include "bmp.h" |
55 | #include "playback.h" | ||
55 | #endif | 56 | #endif |
56 | 57 | ||
57 | #define GUARD_BUFSIZE (32*1024) | 58 | #define GUARD_BUFSIZE (32*1024) |
@@ -908,10 +909,12 @@ static bool fill_buffer(void) | |||
908 | /* Given a file descriptor to a bitmap file, write the bitmap data to the | 909 | /* Given a file descriptor to a bitmap file, write the bitmap data to the |
909 | buffer, with a struct bitmap and the actual data immediately following. | 910 | buffer, with a struct bitmap and the actual data immediately following. |
910 | Return value is the total size (struct + data). */ | 911 | Return value is the total size (struct + data). */ |
911 | static int load_image(int fd, const char *path, struct dim *dim) | 912 | static int load_image(int fd, const char *path, struct bufopen_bitmap_data *data) |
912 | { | 913 | { |
913 | int rc; | 914 | int rc; |
914 | struct bitmap *bmp = (struct bitmap *)&buffer[buf_widx]; | 915 | struct bitmap *bmp = (struct bitmap *)&buffer[buf_widx]; |
916 | struct dim *dim = data->dim; | ||
917 | struct mp3_albumart *aa = data->embedded_albumart; | ||
915 | 918 | ||
916 | /* get the desired image size */ | 919 | /* get the desired image size */ |
917 | bmp->width = dim->width, bmp->height = dim->height; | 920 | bmp->width = dim->width, bmp->height = dim->height; |
@@ -928,8 +931,13 @@ static int load_image(int fd, const char *path, struct dim *dim) | |||
928 | - sizeof(struct bitmap); | 931 | - sizeof(struct bitmap); |
929 | 932 | ||
930 | #ifdef HAVE_JPEG | 933 | #ifdef HAVE_JPEG |
931 | int pathlen = strlen(path); | 934 | if (aa != NULL) |
932 | if (strcmp(path + pathlen - 4, ".bmp")) | 935 | { |
936 | lseek(fd, aa->pos, SEEK_SET); | ||
937 | rc = clip_jpeg_fd(fd, aa->size, bmp, free, FORMAT_NATIVE|FORMAT_DITHER| | ||
938 | FORMAT_RESIZE|FORMAT_KEEP_ASPECT, NULL); | ||
939 | } | ||
940 | else if (strcmp(path + strlen(path) - 4, ".bmp")) | ||
933 | rc = read_jpeg_fd(fd, bmp, free, FORMAT_NATIVE|FORMAT_DITHER| | 941 | rc = read_jpeg_fd(fd, bmp, free, FORMAT_NATIVE|FORMAT_DITHER| |
934 | FORMAT_RESIZE|FORMAT_KEEP_ASPECT, NULL); | 942 | FORMAT_RESIZE|FORMAT_KEEP_ASPECT, NULL); |
935 | else | 943 | else |
@@ -1010,7 +1018,18 @@ int bufopen(const char *file, size_t offset, enum data_type type, | |||
1010 | if (fd < 0) | 1018 | if (fd < 0) |
1011 | return ERR_FILE_ERROR; | 1019 | return ERR_FILE_ERROR; |
1012 | 1020 | ||
1013 | size_t size = filesize(fd); | 1021 | size_t size = 0; |
1022 | #ifdef HAVE_ALBUMART | ||
1023 | if (type == TYPE_BITMAP) | ||
1024 | { /* if albumart is embedded, the complete file is not buffered, | ||
1025 | * but only the jpeg part; filesize() would be wrong */ | ||
1026 | struct bufopen_bitmap_data *aa = (struct bufopen_bitmap_data*)user_data; | ||
1027 | if (aa->embedded_albumart) | ||
1028 | size = aa->embedded_albumart->size; | ||
1029 | } | ||
1030 | #endif | ||
1031 | if (size == 0) | ||
1032 | size = filesize(fd); | ||
1014 | bool can_wrap = type==TYPE_PACKET_AUDIO || type==TYPE_CODEC; | 1033 | bool can_wrap = type==TYPE_PACKET_AUDIO || type==TYPE_CODEC; |
1015 | 1034 | ||
1016 | size_t adjusted_offset = offset; | 1035 | size_t adjusted_offset = offset; |
@@ -1058,7 +1077,7 @@ int bufopen(const char *file, size_t offset, enum data_type type, | |||
1058 | /* Bitmap file: we load the data instead of the file */ | 1077 | /* Bitmap file: we load the data instead of the file */ |
1059 | int rc; | 1078 | int rc; |
1060 | mutex_lock(&llist_mod_mutex); /* Lock because load_bitmap yields */ | 1079 | mutex_lock(&llist_mod_mutex); /* Lock because load_bitmap yields */ |
1061 | rc = load_image(fd, file, (struct dim*)user_data); | 1080 | rc = load_image(fd, file, (struct bufopen_bitmap_data*)user_data); |
1062 | mutex_unlock(&llist_mod_mutex); | 1081 | mutex_unlock(&llist_mod_mutex); |
1063 | if (rc <= 0) | 1082 | if (rc <= 0) |
1064 | { | 1083 | { |
diff --git a/apps/metadata.h b/apps/metadata.h index b99d4d09d6..8d20882835 100644 --- a/apps/metadata.h +++ b/apps/metadata.h | |||
@@ -190,6 +190,22 @@ enum { | |||
190 | ID3_VER_2_4 | 190 | ID3_VER_2_4 |
191 | }; | 191 | }; |
192 | 192 | ||
193 | #ifdef HAVE_ALBUMART | ||
194 | enum mp3_aa_type { | ||
195 | AA_TYPE_UNSYNC = -1, | ||
196 | AA_TYPE_UNKNOWN, | ||
197 | AA_TYPE_BMP, | ||
198 | AA_TYPE_PNG, | ||
199 | AA_TYPE_JPG, | ||
200 | }; | ||
201 | |||
202 | struct mp3_albumart { | ||
203 | enum mp3_aa_type type; | ||
204 | int size; | ||
205 | off_t pos; | ||
206 | }; | ||
207 | #endif | ||
208 | |||
193 | struct mp3entry { | 209 | struct mp3entry { |
194 | char path[MAX_PATH]; | 210 | char path[MAX_PATH]; |
195 | char* title; | 211 | char* title; |
@@ -277,6 +293,11 @@ struct mp3entry { | |||
277 | long album_peak; | 293 | long album_peak; |
278 | #endif | 294 | #endif |
279 | 295 | ||
296 | #ifdef HAVE_ALBUMART | ||
297 | bool embed_albumart; | ||
298 | struct mp3_albumart albumart; | ||
299 | #endif | ||
300 | |||
280 | /* Cuesheet support */ | 301 | /* Cuesheet support */ |
281 | struct cuesheet *cuesheet; | 302 | struct cuesheet *cuesheet; |
282 | 303 | ||
diff --git a/apps/metadata/id3tags.c b/apps/metadata/id3tags.c index 75056a273c..a20a59f06e 100644 --- a/apps/metadata/id3tags.c +++ b/apps/metadata/id3tags.c | |||
@@ -290,6 +290,63 @@ static int parsegenre( struct mp3entry* entry, char* tag, int bufferpos ) | |||
290 | } | 290 | } |
291 | } | 291 | } |
292 | 292 | ||
293 | #ifdef HAVE_ALBUMART | ||
294 | /* parse embed albumart */ | ||
295 | static int parsealbumart( struct mp3entry* entry, char* tag, int bufferpos ) | ||
296 | { | ||
297 | entry->embed_albumart = false; | ||
298 | |||
299 | /* we currently don't support unsynchronizing albumart */ | ||
300 | if (entry->albumart.type == AA_TYPE_UNSYNC) | ||
301 | return bufferpos; | ||
302 | |||
303 | entry->albumart.type = AA_TYPE_UNKNOWN; | ||
304 | |||
305 | char *start = tag; | ||
306 | /* skip text encoding */ | ||
307 | tag += 1; | ||
308 | |||
309 | if (memcmp(tag, "image/", 6) == 0) | ||
310 | { | ||
311 | /* ID3 v2.3+ */ | ||
312 | tag += 6; | ||
313 | if (strcmp(tag, "jpeg") == 0) | ||
314 | { | ||
315 | entry->albumart.type = AA_TYPE_JPG; | ||
316 | tag += 5; | ||
317 | } | ||
318 | else if (strcmp(tag, "png") == 0) | ||
319 | { | ||
320 | entry->albumart.type = AA_TYPE_PNG; | ||
321 | tag += 4; | ||
322 | } | ||
323 | } | ||
324 | else | ||
325 | { | ||
326 | /* ID3 v2.2 */ | ||
327 | if (memcmp(tag, "JPG", 3) == 0) | ||
328 | entry->albumart.type = AA_TYPE_JPG; | ||
329 | else if (memcmp(tag, "PNG", 3) == 0) | ||
330 | entry->albumart.type = AA_TYPE_PNG; | ||
331 | tag += 3; | ||
332 | } | ||
333 | |||
334 | if (entry->albumart.type != AA_TYPE_UNKNOWN) | ||
335 | { | ||
336 | /* skip picture type */ | ||
337 | tag += 1; | ||
338 | /* skip description */ | ||
339 | tag = strchr(tag, '\0') + 1; | ||
340 | /* fixup offset&size for image data */ | ||
341 | entry->albumart.pos += tag - start; | ||
342 | entry->albumart.size -= tag - start; | ||
343 | entry->embed_albumart = true; | ||
344 | } | ||
345 | /* return bufferpos as we didn't store anything in id3v2buf */ | ||
346 | return bufferpos; | ||
347 | } | ||
348 | #endif | ||
349 | |||
293 | /* parse user defined text, looking for album artist and replaygain | 350 | /* parse user defined text, looking for album artist and replaygain |
294 | * information. | 351 | * information. |
295 | */ | 352 | */ |
@@ -439,6 +496,10 @@ static const struct tag_resolver taglist[] = { | |||
439 | { "COM", 3, offsetof(struct mp3entry, comment), NULL, false }, | 496 | { "COM", 3, offsetof(struct mp3entry, comment), NULL, false }, |
440 | { "TCON", 4, offsetof(struct mp3entry, genre_string), &parsegenre, false }, | 497 | { "TCON", 4, offsetof(struct mp3entry, genre_string), &parsegenre, false }, |
441 | { "TCO", 3, offsetof(struct mp3entry, genre_string), &parsegenre, false }, | 498 | { "TCO", 3, offsetof(struct mp3entry, genre_string), &parsegenre, false }, |
499 | #ifdef HAVE_ALBUMART | ||
500 | { "APIC", 4, 0, &parsealbumart, true }, | ||
501 | { "PIC", 3, 0, &parsealbumart, true }, | ||
502 | #endif | ||
442 | { "TXXX", 4, 0, &parseuser, false }, | 503 | { "TXXX", 4, 0, &parseuser, false }, |
443 | #if CONFIG_CODEC == SWCODEC | 504 | #if CONFIG_CODEC == SWCODEC |
444 | { "RVA2", 4, 0, &parserva2, true }, | 505 | { "RVA2", 4, 0, &parserva2, true }, |
@@ -961,6 +1022,21 @@ void setid3v2title(int fd, struct mp3entry *entry) | |||
961 | if (ptag && !*ptag) | 1022 | if (ptag && !*ptag) |
962 | *ptag = tag; | 1023 | *ptag = tag; |
963 | 1024 | ||
1025 | /* albumart */ | ||
1026 | if ((!entry->embed_albumart) && | ||
1027 | ((tr->tag_length == 4 && !memcmp( header, "APIC", 4)) || | ||
1028 | (tr->tag_length == 3 && !memcmp( header, "PIC" , 3)))) | ||
1029 | { | ||
1030 | if (unsynch || (global_unsynch && version <= ID3_VER_2_3)) | ||
1031 | entry->albumart.type = AA_TYPE_UNSYNC; | ||
1032 | else | ||
1033 | { | ||
1034 | entry->albumart.pos = lseek(fd, 0, SEEK_CUR) - framelen; | ||
1035 | entry->albumart.size = totframelen; | ||
1036 | entry->albumart.type = AA_TYPE_UNKNOWN; | ||
1037 | } | ||
1038 | } | ||
1039 | |||
964 | if( tr->ppFunc ) | 1040 | if( tr->ppFunc ) |
965 | bufferpos = tr->ppFunc(entry, tag, bufferpos); | 1041 | bufferpos = tr->ppFunc(entry, tag, bufferpos); |
966 | 1042 | ||
diff --git a/apps/playback.c b/apps/playback.c index fe7b74893a..9030161f4a 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -142,6 +142,7 @@ static struct cuesheet *curr_cue = NULL; | |||
142 | #define MAX_MULTIPLE_AA SKINNABLE_SCREENS_COUNT | 142 | #define MAX_MULTIPLE_AA SKINNABLE_SCREENS_COUNT |
143 | 143 | ||
144 | #ifdef HAVE_ALBUMART | 144 | #ifdef HAVE_ALBUMART |
145 | |||
145 | static struct albumart_slot { | 146 | static struct albumart_slot { |
146 | struct dim dim; /* holds width, height of the albumart */ | 147 | struct dim dim; /* holds width, height of the albumart */ |
147 | int used; /* counter, increments if something uses it */ | 148 | int used; /* counter, increments if something uses it */ |
@@ -228,7 +229,6 @@ static bool audio_have_tracks(void); | |||
228 | static void audio_reset_buffer(void); | 229 | static void audio_reset_buffer(void); |
229 | static void audio_stop_playback(void); | 230 | static void audio_stop_playback(void); |
230 | 231 | ||
231 | |||
232 | /**************************************/ | 232 | /**************************************/ |
233 | 233 | ||
234 | 234 | ||
@@ -647,6 +647,7 @@ bool audio_peek_track(struct mp3entry** id3, int offset) | |||
647 | } | 647 | } |
648 | 648 | ||
649 | #ifdef HAVE_ALBUMART | 649 | #ifdef HAVE_ALBUMART |
650 | |||
650 | int playback_current_aa_hid(int slot) | 651 | int playback_current_aa_hid(int slot) |
651 | { | 652 | { |
652 | if (slot < 0) | 653 | if (slot < 0) |
@@ -656,13 +657,13 @@ int playback_current_aa_hid(int slot) | |||
656 | 657 | ||
657 | cur_idx = track_ridx + offset; | 658 | cur_idx = track_ridx + offset; |
658 | cur_idx &= MAX_TRACK_MASK; | 659 | cur_idx &= MAX_TRACK_MASK; |
659 | |||
660 | return tracks[cur_idx].aa_hid[slot]; | 660 | return tracks[cur_idx].aa_hid[slot]; |
661 | } | 661 | } |
662 | 662 | ||
663 | int playback_claim_aa_slot(struct dim *dim) | 663 | int playback_claim_aa_slot(struct dim *dim) |
664 | { | 664 | { |
665 | int i; | 665 | int i; |
666 | |||
666 | /* first try to find a slot already having the size to reuse it | 667 | /* first try to find a slot already having the size to reuse it |
667 | * since we don't want albumart of the same size buffered multiple times */ | 668 | * since we don't want albumart of the same size buffered multiple times */ |
668 | FOREACH_ALBUMART(i) | 669 | FOREACH_ALBUMART(i) |
@@ -693,6 +694,7 @@ void playback_release_aa_slot(int slot) | |||
693 | { | 694 | { |
694 | /* invalidate the albumart_slot */ | 695 | /* invalidate the albumart_slot */ |
695 | struct albumart_slot *aa_slot = &albumart_slots[slot]; | 696 | struct albumart_slot *aa_slot = &albumart_slots[slot]; |
697 | |||
696 | if (aa_slot->used > 0) | 698 | if (aa_slot->used > 0) |
697 | aa_slot->used--; | 699 | aa_slot->used--; |
698 | } | 700 | } |
@@ -1315,19 +1317,37 @@ static void audio_finish_load_track(void) | |||
1315 | { | 1317 | { |
1316 | int i; | 1318 | int i; |
1317 | char aa_path[MAX_PATH]; | 1319 | char aa_path[MAX_PATH]; |
1320 | |||
1318 | FOREACH_ALBUMART(i) | 1321 | FOREACH_ALBUMART(i) |
1319 | { | 1322 | { |
1320 | /* albumart_slots may change during a yield of bufopen, | 1323 | /* albumart_slots may change during a yield of bufopen, |
1321 | * but that's no problem */ | 1324 | * but that's no problem */ |
1322 | if (tracks[track_widx].aa_hid[i] >= 0 || !albumart_slots[i].used) | 1325 | if (tracks[track_widx].aa_hid[i] >= 0 || !albumart_slots[i].used) |
1323 | continue; | 1326 | continue; |
1327 | |||
1328 | /* we can only decode jpeg for embedded AA */ | ||
1329 | bool embedded_albumart = | ||
1330 | track_id3->embed_albumart && track_id3->albumart.type == AA_TYPE_JPG; | ||
1324 | /* find_albumart will error out if the wps doesn't have AA */ | 1331 | /* find_albumart will error out if the wps doesn't have AA */ |
1325 | if (find_albumart(track_id3, aa_path, sizeof(aa_path), | 1332 | if (embedded_albumart || find_albumart(track_id3, aa_path, |
1326 | &(albumart_slots[i].dim))) | 1333 | sizeof(aa_path), &(albumart_slots[i].dim))) |
1327 | { | 1334 | { |
1328 | int aa_hid = bufopen(aa_path, 0, TYPE_BITMAP, | 1335 | int aa_hid; |
1329 | &(albumart_slots[i].dim)); | 1336 | struct bufopen_bitmap_data user_data = { |
1330 | 1337 | .dim = &(albumart_slots[i].dim), | |
1338 | .embedded_albumart = NULL, | ||
1339 | }; | ||
1340 | if (embedded_albumart) | ||
1341 | { | ||
1342 | user_data.embedded_albumart = &(track_id3->albumart); | ||
1343 | aa_hid = bufopen(track_id3->path, 0, | ||
1344 | TYPE_BITMAP, &user_data); | ||
1345 | } | ||
1346 | else | ||
1347 | { | ||
1348 | aa_hid = bufopen(aa_path, 0, TYPE_BITMAP, | ||
1349 | &user_data); | ||
1350 | } | ||
1331 | if(aa_hid == ERR_BUFFER_FULL) | 1351 | if(aa_hid == ERR_BUFFER_FULL) |
1332 | { | 1352 | { |
1333 | filling = STATE_FULL; | 1353 | filling = STATE_FULL; |
@@ -1342,7 +1362,6 @@ static void audio_finish_load_track(void) | |||
1342 | tracks[track_widx].aa_hid[i] = aa_hid; | 1362 | tracks[track_widx].aa_hid[i] = aa_hid; |
1343 | } | 1363 | } |
1344 | } | 1364 | } |
1345 | |||
1346 | } | 1365 | } |
1347 | #endif | 1366 | #endif |
1348 | 1367 | ||
diff --git a/apps/playback.h b/apps/playback.h index 27e27ff240..475e2fb662 100644 --- a/apps/playback.h +++ b/apps/playback.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #ifdef HAVE_ALBUMART | 29 | #ifdef HAVE_ALBUMART |
30 | 30 | ||
31 | #include "bmp.h" | 31 | #include "bmp.h" |
32 | #include "metadata.h" | ||
32 | /* | 33 | /* |
33 | * Returns the handle id of the buffered albumart for the given slot id | 34 | * Returns the handle id of the buffered albumart for the given slot id |
34 | **/ | 35 | **/ |
@@ -50,6 +51,12 @@ int playback_claim_aa_slot(struct dim *dim); | |||
50 | * | 51 | * |
51 | * Save to call from other threads */ | 52 | * Save to call from other threads */ |
52 | void playback_release_aa_slot(int slot); | 53 | void playback_release_aa_slot(int slot); |
54 | |||
55 | struct bufopen_bitmap_data { | ||
56 | struct dim *dim; | ||
57 | struct mp3_albumart *embedded_albumart; | ||
58 | }; | ||
59 | |||
53 | #endif | 60 | #endif |
54 | 61 | ||
55 | /* Functions */ | 62 | /* Functions */ |
diff --git a/apps/recorder/jpeg_load.c b/apps/recorder/jpeg_load.c index 1af65fab6c..cd13934921 100644 --- a/apps/recorder/jpeg_load.c +++ b/apps/recorder/jpeg_load.c | |||
@@ -75,12 +75,12 @@ struct jpeg | |||
75 | { | 75 | { |
76 | #ifdef JPEG_FROM_MEM | 76 | #ifdef JPEG_FROM_MEM |
77 | unsigned char *data; | 77 | unsigned char *data; |
78 | unsigned long len; | ||
79 | #else | 78 | #else |
80 | int fd; | 79 | int fd; |
81 | int buf_left; | 80 | int buf_left; |
82 | int buf_index; | 81 | int buf_index; |
83 | #endif | 82 | #endif |
83 | unsigned long len; | ||
84 | unsigned long int bitbuf; | 84 | unsigned long int bitbuf; |
85 | int bitbuf_bits; | 85 | int bitbuf_bits; |
86 | int marker_ind; | 86 | int marker_ind; |
@@ -888,8 +888,12 @@ INLINE void jpeg_putc(struct jpeg* p_jpeg) | |||
888 | #else | 888 | #else |
889 | INLINE void fill_buf(struct jpeg* p_jpeg) | 889 | INLINE void fill_buf(struct jpeg* p_jpeg) |
890 | { | 890 | { |
891 | p_jpeg->buf_left = read(p_jpeg->fd, p_jpeg->buf, JPEG_READ_BUF_SIZE); | 891 | p_jpeg->buf_left = read(p_jpeg->fd, p_jpeg->buf, |
892 | (p_jpeg->len >= JPEG_READ_BUF_SIZE)? | ||
893 | JPEG_READ_BUF_SIZE : p_jpeg->len); | ||
892 | p_jpeg->buf_index = 0; | 894 | p_jpeg->buf_index = 0; |
895 | if (p_jpeg->buf_left > 0) | ||
896 | p_jpeg->len -= p_jpeg->buf_left; | ||
893 | } | 897 | } |
894 | 898 | ||
895 | static unsigned char *jpeg_getc(struct jpeg* p_jpeg) | 899 | static unsigned char *jpeg_getc(struct jpeg* p_jpeg) |
@@ -1960,7 +1964,9 @@ block_end: | |||
1960 | * | 1964 | * |
1961 | *****************************************************************************/ | 1965 | *****************************************************************************/ |
1962 | #ifndef JPEG_FROM_MEM | 1966 | #ifndef JPEG_FROM_MEM |
1963 | int read_jpeg_file(const char* filename, | 1967 | int clip_jpeg_file(const char* filename, |
1968 | int offset, | ||
1969 | unsigned long jpeg_size, | ||
1964 | struct bitmap *bm, | 1970 | struct bitmap *bm, |
1965 | int maxsize, | 1971 | int maxsize, |
1966 | int format, | 1972 | int format, |
@@ -1975,11 +1981,20 @@ int read_jpeg_file(const char* filename, | |||
1975 | DEBUGF("read_jpeg_file: can't open '%s', rc: %d\n", filename, fd); | 1981 | DEBUGF("read_jpeg_file: can't open '%s', rc: %d\n", filename, fd); |
1976 | return fd * 10 - 1; | 1982 | return fd * 10 - 1; |
1977 | } | 1983 | } |
1978 | 1984 | lseek(fd, offset, SEEK_SET); | |
1979 | ret = read_jpeg_fd(fd, bm, maxsize, format, cformat); | 1985 | ret = clip_jpeg_fd(fd, jpeg_size, bm, maxsize, format, cformat); |
1980 | close(fd); | 1986 | close(fd); |
1981 | return ret; | 1987 | return ret; |
1982 | } | 1988 | } |
1989 | |||
1990 | int read_jpeg_file(const char* filename, | ||
1991 | struct bitmap *bm, | ||
1992 | int maxsize, | ||
1993 | int format, | ||
1994 | const struct custom_format *cformat) | ||
1995 | { | ||
1996 | return clip_jpeg_file(filename, 0, 0, bm, maxsize, format, cformat); | ||
1997 | } | ||
1983 | #endif | 1998 | #endif |
1984 | 1999 | ||
1985 | static int calc_scale(int in_size, int out_size) | 2000 | static int calc_scale(int in_size, int out_size) |
@@ -2014,10 +2029,11 @@ int get_jpeg_dim_mem(unsigned char *data, unsigned long len, | |||
2014 | return 0; | 2029 | return 0; |
2015 | } | 2030 | } |
2016 | 2031 | ||
2017 | int decode_jpeg_mem(unsigned char *data, unsigned long len, | 2032 | int decode_jpeg_mem(unsigned char *data, |
2018 | #else | 2033 | #else |
2019 | int read_jpeg_fd(int fd, | 2034 | int clip_jpeg_fd(int fd, |
2020 | #endif | 2035 | #endif |
2036 | unsigned long len, | ||
2021 | struct bitmap *bm, | 2037 | struct bitmap *bm, |
2022 | int maxsize, | 2038 | int maxsize, |
2023 | int format, | 2039 | int format, |
@@ -2039,11 +2055,13 @@ int read_jpeg_fd(int fd, | |||
2039 | return -1; | 2055 | return -1; |
2040 | #endif | 2056 | #endif |
2041 | memset(p_jpeg, 0, sizeof(struct jpeg)); | 2057 | memset(p_jpeg, 0, sizeof(struct jpeg)); |
2058 | p_jpeg->len = len; | ||
2042 | #ifdef JPEG_FROM_MEM | 2059 | #ifdef JPEG_FROM_MEM |
2043 | p_jpeg->data = data; | 2060 | p_jpeg->data = data; |
2044 | p_jpeg->len = len; | ||
2045 | #else | 2061 | #else |
2046 | p_jpeg->fd = fd; | 2062 | p_jpeg->fd = fd; |
2063 | if (p_jpeg->len == 0) | ||
2064 | p_jpeg->len = filesize(p_jpeg->fd); | ||
2047 | #endif | 2065 | #endif |
2048 | status = process_markers(p_jpeg); | 2066 | status = process_markers(p_jpeg); |
2049 | #ifndef JPEG_FROM_MEM | 2067 | #ifndef JPEG_FROM_MEM |
@@ -2212,4 +2230,13 @@ int read_jpeg_fd(int fd, | |||
2212 | return 0; | 2230 | return 0; |
2213 | } | 2231 | } |
2214 | 2232 | ||
2233 | int read_jpeg_fd(int fd, | ||
2234 | struct bitmap *bm, | ||
2235 | int maxsize, | ||
2236 | int format, | ||
2237 | const struct custom_format *cformat) | ||
2238 | { | ||
2239 | return clip_jpeg_fd(fd, 0, bm, maxsize, format, cformat); | ||
2240 | } | ||
2241 | |||
2215 | /**************** end JPEG code ********************/ | 2242 | /**************** end JPEG code ********************/ |
diff --git a/apps/recorder/jpeg_load.h b/apps/recorder/jpeg_load.h index 73b6c51bf3..6ff96dabad 100644 --- a/apps/recorder/jpeg_load.h +++ b/apps/recorder/jpeg_load.h | |||
@@ -44,4 +44,27 @@ int read_jpeg_fd(int fd, | |||
44 | int format, | 44 | int format, |
45 | const struct custom_format *cformat); | 45 | const struct custom_format *cformat); |
46 | 46 | ||
47 | /** | ||
48 | * read embedded jpeg files as above. Needs an offset and length into | ||
49 | * the file | ||
50 | **/ | ||
51 | int clip_jpeg_file(const char* filename, | ||
52 | int offset, | ||
53 | unsigned long jpeg_size, | ||
54 | struct bitmap *bm, | ||
55 | int maxsize, | ||
56 | int format, | ||
57 | const struct custom_format *cformat); | ||
58 | |||
59 | /** | ||
60 | * read embedded jpeg files as above. Needs an open file descripter, and | ||
61 | * assumes the caller has lseek()'d to the start of the jpeg blob | ||
62 | **/ | ||
63 | int clip_jpeg_fd(int fd, | ||
64 | unsigned long jpeg_size, | ||
65 | struct bitmap *bm, | ||
66 | int maxsize, | ||
67 | int format, | ||
68 | const struct custom_format *cformat); | ||
69 | |||
47 | #endif /* _JPEG_JPEG_DECODER_H */ | 70 | #endif /* _JPEG_JPEG_DECODER_H */ |