A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 234 lines 6.4 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2010 Marcin Bukat 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 * KIND, either express or implied. 19 * 20 ****************************************************************************/ 21 22#include "plugin.h" 23#include "lcd.h" 24#include <lib/pluginlib_bmp.h> 25#include "../imageviewer.h" 26#include "ppm_decoder.h" 27#include "bmp.h" 28 29static char print[32]; /* use a common snprintf() buffer */ 30 31/* decompressed image in the possible sizes (1,2,4,8), wasting the other */ 32static unsigned char *disp[9]; 33static unsigned char *disp_buf; 34static struct ppm_info ppm; 35 36#if defined(HAVE_LCD_COLOR) 37#define resize_bitmap smooth_resize_bitmap 38#else 39#define resize_bitmap grey_resize_bitmap 40#endif 41 42#if defined(USEGSLIB) && (CONFIG_PLATFORM & PLATFORM_HOSTED) 43/* hack: fix error "undefined reference to `_grey_info'". */ 44GREY_INFO_STRUCT 45#endif /* USEGSLIB */ 46 47static void draw_image_rect(struct image_info *info, 48 int x, int y, int width, int height) 49{ 50 unsigned char **pdisp = (unsigned char **)info->data; 51 52#ifdef HAVE_LCD_COLOR 53 rb->lcd_bitmap_part((fb_data *)*pdisp, info->x + x, info->y + y, 54 STRIDE(SCREEN_MAIN, info->width, info->height), 55 x + MAX(0, (LCD_WIDTH-info->width)/2), 56 y + MAX(0, (LCD_HEIGHT-info->height)/2), 57 width, height); 58#else 59 mylcd_ub_gray_bitmap_part(*pdisp, 60 info->x + x, info->y + y, info->width, 61 x + MAX(0, (LCD_WIDTH-info->width)/2), 62 y + MAX(0, (LCD_HEIGHT-info->height)/2), 63 width, height); 64#endif 65} 66 67static int img_mem(int ds) 68{ 69 70#ifdef USEGSLIB 71 return (ppm.x/ds) * (ppm.y/ds); 72#else 73 return (ppm.x/ds) * (ppm.y/ds) * FB_DATA_SZ; 74#endif 75} 76 77static int load_image(char *filename, struct image_info *info, 78 unsigned char *buf, ssize_t *buf_size, 79 int offset, int filesize) 80{ 81 int fd; 82 int rc = PLUGIN_OK; 83 long time = 0; /* measured ticks */ 84 int w, h; /* used to center output */ 85 86 unsigned char *memory, *memory_max; 87 size_t memory_size; 88 89 /* cleanup */ 90 memset(&disp, 0, sizeof(disp)); 91 92 /* align buffer */ 93 memory = (unsigned char *)((intptr_t)(buf + 3) & ~3); 94 memory_max = (unsigned char *)((intptr_t)(memory + *buf_size) & ~3); 95 memory_size = memory_max - memory; 96 97 fd = rb->open(filename, O_RDONLY); 98 if (fd < 0) 99 { 100 rb->splashf(HZ, "err opening %s: %d", filename, fd); 101 return PLUGIN_ERROR; 102 } 103 104 if (offset) 105 { 106 rb->lseek(fd, offset, SEEK_SET); 107 } 108 else 109 { 110 filesize = rb->filesize(fd); 111 } 112 DEBUGF("reading file '%s'\n", filename); 113 114 if (!iv->running_slideshow) 115 { 116 rb->lcd_puts(0, 0, rb->strrchr(filename,'/')+1); 117 rb->lcd_putsf(0, 1, "loading %zu bytes", filesize); 118 rb->lcd_update(); 119 } 120 121 /* init decoder struct */ 122 ppm.buf = memory; 123 ppm.buf_size = memory_size; 124 125 /* the actual decoding */ 126 time = *rb->current_tick; 127#ifdef HAVE_ADJUSTABLE_CPU_FREQ 128 rb->cpu_boost(true); 129 rc = read_ppm(fd, &ppm); 130 rb->cpu_boost(false); 131#else 132 rc = read_ppm(fd, &ppm); 133#endif /*HAVE_ADJUSTABLE_CPU_FREQ*/ 134 time = *rb->current_tick - time; 135 136 rb->close(fd); 137 138 if (rc != PLUGIN_OK) 139 { 140 return rc; 141 } 142 143 if (!iv->running_slideshow) 144 { 145 rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ); 146 rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */ 147 rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print); 148 rb->lcd_update(); 149 } 150 151 info->x_size = ppm.x; 152 info->y_size = ppm.y; 153 154 ppm.native_img_size = (ppm.native_img_size + 3) & ~3; 155 disp_buf = buf + ppm.native_img_size; 156 *buf_size = memory_max - disp_buf; 157 158 return PLUGIN_OK; 159} 160 161static int get_image(struct image_info *info, int frame, int ds) 162{ 163 (void)frame; 164 unsigned char **p_disp = &disp[ds]; /* short cut */ 165 struct ppm_info *p_ppm = &ppm; 166 167 info->width = ppm.x / ds; 168 info->height = ppm.y / ds; 169 info->data = p_disp; 170 171 if (*p_disp != NULL) 172 { 173 /* we still have it */ 174 return PLUGIN_OK; 175 } 176 177 /* assign image buffer */ 178 if (ds > 1) 179 { 180 if (!iv->running_slideshow) 181 { 182 rb->lcd_putsf(0, 3, "resizing %d*%d", info->width, info->height); 183 rb->lcd_update(); 184 } 185 186 struct bitmap bmp_src, bmp_dst; 187 int size = img_mem(ds); 188 189 if (disp_buf + size >= p_ppm->buf + p_ppm->buf_size) 190 { 191 /* have to discard the current */ 192 int i; 193 for (i=1; i<=8; i++) 194 disp[i] = NULL; /* invalidate all bitmaps */ 195 196 /* start again from the beginning of the buffer */ 197 disp_buf = p_ppm->buf + p_ppm->native_img_size; 198 } 199 200 *p_disp = disp_buf; 201 disp_buf += size; 202 203 bmp_src.width = ppm.x; 204 bmp_src.height = ppm.y; 205 bmp_src.data = ppm.buf; 206 207 bmp_dst.width = info->width; 208 bmp_dst.height = info->height; 209 bmp_dst.data = *p_disp; 210#ifdef HAVE_ADJUSTABLE_CPU_FREQ 211 rb->cpu_boost(true); 212 resize_bitmap(&bmp_src, &bmp_dst); 213 rb->cpu_boost(false); 214#else 215 resize_bitmap(&bmp_src, &bmp_dst); 216#endif /*HAVE_ADJUSTABLE_CPU_FREQ*/ 217 } 218 else 219 { 220 *p_disp = p_ppm->buf; 221 } 222 223 return PLUGIN_OK; 224} 225 226const struct image_decoder image_decoder = { 227 true, 228 img_mem, 229 load_image, 230 get_image, 231 draw_image_rect, 232}; 233 234IMGDEC_HEADER