Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add ppm and rppm viewer by Alexander Papst


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17835 a1c6a512-1295-4272-9138-f99709370657

+337
+1
apps/plugins/CATEGORIES
··· 54 54 pictureflow,demos 55 55 plasma,demos 56 56 pong,games 57 + ppmviewer,viewers 57 58 properties,viewers 58 59 random_folder_advance_config,apps 59 60 reversi,games
+1
apps/plugins/SOURCES
··· 60 60 jpeg.c 61 61 mandelbrot.c 62 62 plasma.c 63 + ppmviewer.c 63 64 64 65 blackjack.c 65 66 bounce.c
+334
apps/plugins/ppmviewer.c
··· 1 + /***************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// __ \_/ ___\| |/ /| __ \ / __ \ \/ / 5 + * Jukebox | | ( (__) ) \___| ( | \_\ ( (__) ) ( 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * $Id$ 9 + * 10 + * Copyright (C) 2008 Alexander Papst 11 + * 12 + * All files in this archive are subject to the GNU General Public License. 13 + * See the file COPYING in the source tree root for full license agreement. 14 + * 15 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 16 + * KIND, either express or implied. 17 + * 18 + ****************************************************************************/ 19 + 20 + #include "plugin.h" 21 + #include "bmp.h" 22 + 23 + #if defined(HAVE_LCD_COLOR) 24 + 25 + PLUGIN_HEADER 26 + 27 + /* Magic constants. */ 28 + #define PPM_MAGIC1 'P' 29 + #define PPM_MAGIC2 '3' 30 + #define RPPM_MAGIC2 '6' 31 + #define PPM_FORMAT (PPM_MAGIC1 * 256 + PPM_MAGIC2) 32 + #define RPPM_FORMAT (PPM_MAGIC1 * 256 + RPPM_MAGIC2) 33 + 34 + #define PPM_OVERALLMAXVAL 65535 35 + #define PPM_MAXSIZE (300*1024)/sizeof(fb_data) 36 + 37 + #define ppm_error(...) rb->splash(HZ*2, __VA_ARGS__ ) 38 + 39 + static fb_data buffer[PPM_MAXSIZE]; 40 + static fb_data lcd_buf[LCD_WIDTH * LCD_HEIGHT]; 41 + 42 + static const struct plugin_api* rb; /* global api struct pointer */ 43 + 44 + int ppm_read_magic_number(int fd) 45 + { 46 + char i1, i2; 47 + if(!rb->read(fd, &i1, 1) || !rb->read(fd, &i2, 1)) 48 + { 49 + ppm_error( "Error reading magic number from ppm image stream. "\ 50 + "Most often, this means your input file is empty." ); 51 + return PLUGIN_ERROR; 52 + } 53 + return i1 * 256 + i2; 54 + } 55 + 56 + char ppm_getc(int fd) 57 + { 58 + char ch; 59 + 60 + if (!rb->read(fd, &ch, 1)) { 61 + ppm_error("EOF. Read error reading a byte"); 62 + return PLUGIN_ERROR; 63 + } 64 + 65 + if (ch == '#') { 66 + do { 67 + if (!rb->read(fd, &ch, 1)) { 68 + ppm_error("EOF. Read error reading a byte"); 69 + return PLUGIN_ERROR; 70 + } 71 + } while (ch != '\n' && ch != '\r'); 72 + } 73 + return ch; 74 + } 75 + 76 + int ppm_getuint(int fd) 77 + { 78 + char ch; 79 + int i; 80 + int digitVal; 81 + 82 + do { 83 + ch = ppm_getc(fd); 84 + } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); 85 + 86 + if (ch < '0' || ch > '9') { 87 + ppm_error("Junk (%c) in file where an integer should be.", ch); 88 + return PLUGIN_ERROR; 89 + } 90 + 91 + i = 0; 92 + 93 + do { 94 + digitVal = ch - '0'; 95 + 96 + if (i > INT_MAX/10 - digitVal) { 97 + ppm_error("ASCII decimal integer in file is "\ 98 + "too large to be processed."); 99 + return PLUGIN_ERROR; 100 + } 101 + 102 + i = i * 10 + digitVal; 103 + ch = ppm_getc(fd); 104 + 105 + } while (ch >= '0' && ch <= '9'); 106 + 107 + return i; 108 + } 109 + 110 + int ppm_getrawbyte(int fd) 111 + { 112 + unsigned char by; 113 + 114 + if (!rb->read(fd, &by, 1)) { 115 + ppm_error("EOF. Read error while reading a one-byte sample."); 116 + return PLUGIN_ERROR; 117 + } 118 + 119 + return (int)by; 120 + } 121 + 122 + int ppm_getrawsample(int fd, int const maxval) 123 + { 124 + if (maxval < 256) { 125 + /* The sample is just one byte. Read it. */ 126 + return(ppm_getrawbyte(fd)); 127 + } else { 128 + /* The sample is two bytes. Read both. */ 129 + unsigned char byte_pair[2]; 130 + 131 + if (!rb->read(fd, byte_pair, 2)) { 132 + ppm_error("EOF. Read error while reading a long sample."); 133 + return PLUGIN_ERROR; 134 + } 135 + return((byte_pair[0]<<8) | byte_pair[1]); 136 + } 137 + } 138 + 139 + int read_ppm_init_rest(int fd, 140 + int * const cols, 141 + int * const rows, 142 + int * const maxval) 143 + { 144 + /* Read size. */ 145 + *cols = ppm_getuint(fd); 146 + *rows = ppm_getuint(fd); 147 + 148 + if ((long unsigned int)(*cols * *rows) > PPM_MAXSIZE) { 149 + ppm_error("Imagesize (%ld pixels) is too large. "\ 150 + "The maximum allowed is %ld.", 151 + (long unsigned int)(*cols * *rows), 152 + (long unsigned int)PPM_MAXSIZE); 153 + return PLUGIN_ERROR; 154 + } 155 + 156 + /* Read maxval. */ 157 + *maxval = ppm_getuint(fd); 158 + 159 + if (*maxval > PPM_OVERALLMAXVAL) { 160 + ppm_error("maxval of input image (%u) is too large. "\ 161 + "The maximum allowed by the PPM is %u.", 162 + *maxval, PPM_OVERALLMAXVAL); 163 + return PLUGIN_ERROR; 164 + } 165 + if (*maxval == 0) { 166 + ppm_error("maxval of input image is zero."); 167 + return PLUGIN_ERROR; 168 + } 169 + return 1; 170 + } 171 + 172 + void read_ppm_init(int fd, 173 + int * const cols, 174 + int * const rows, 175 + int * const maxval, 176 + int * const format) 177 + { 178 + /* Check magic number. */ 179 + *format = ppm_read_magic_number( fd ); 180 + 181 + if (*format == PLUGIN_ERROR) return; 182 + switch (*format) { 183 + case PPM_FORMAT: 184 + case RPPM_FORMAT: 185 + if(read_ppm_init_rest(fd, cols, rows, maxval) == PLUGIN_ERROR) { 186 + *format = PLUGIN_ERROR; 187 + } 188 + break; 189 + 190 + default: 191 + ppm_error( "Bad magic number - not a ppm or rppm file." ); 192 + *format = PLUGIN_ERROR; 193 + } 194 + } 195 + 196 + int read_ppm_row(int fd, 197 + int const row, 198 + int const cols, 199 + int const maxval, 200 + int const format) 201 + { 202 + int col; 203 + int r, g, b; 204 + switch (format) { 205 + case PPM_FORMAT: 206 + for (col = 0; col < cols; ++col) { 207 + r = ppm_getuint(fd); 208 + g = ppm_getuint(fd); 209 + b = ppm_getuint(fd); 210 + 211 + if (r == PLUGIN_ERROR || g == PLUGIN_ERROR || 212 + b == PLUGIN_ERROR) 213 + { 214 + return PLUGIN_ERROR; 215 + } 216 + buffer[(cols * row) + col] = LCD_RGBPACK( 217 + (255 / maxval) * r, 218 + (255 / maxval) * g, 219 + (255 / maxval) * b); 220 + } 221 + break; 222 + 223 + case RPPM_FORMAT: 224 + for (col = 0; col < cols; ++col) { 225 + r = ppm_getrawsample(fd, maxval); 226 + g = ppm_getrawsample(fd, maxval); 227 + b = ppm_getrawsample(fd, maxval); 228 + 229 + if (r == PLUGIN_ERROR || g == PLUGIN_ERROR || 230 + b == PLUGIN_ERROR) 231 + { 232 + return PLUGIN_ERROR; 233 + } 234 + buffer[(cols * row) + col] = LCD_RGBPACK( 235 + (255 / maxval) * r, 236 + (255 / maxval) * g, 237 + (255 / maxval) * b); 238 + } 239 + break; 240 + 241 + default: 242 + ppm_error("What?!"); 243 + return PLUGIN_ERROR; 244 + } 245 + return 1; 246 + } 247 + 248 + int read_ppm(int fd, 249 + int * const cols, 250 + int * const rows, 251 + int * const maxval) 252 + { 253 + int row; 254 + int format; 255 + 256 + read_ppm_init(fd, cols, rows, maxval, &format); 257 + 258 + if(format == PLUGIN_ERROR) { 259 + return PLUGIN_ERROR; 260 + } 261 + 262 + for (row = 0; row < *rows; ++row) { 263 + if( read_ppm_row(fd, row, *cols, *maxval, format) == PLUGIN_ERROR) { 264 + return PLUGIN_ERROR; 265 + } 266 + } 267 + return 1; 268 + } 269 + 270 + /* this is the plugin entry point */ 271 + enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter) 272 + { 273 + static char filename[MAX_PATH]; 274 + int fd; 275 + 276 + int cols; 277 + int rows; 278 + int maxval; 279 + 280 + int result; 281 + 282 + struct bitmap small_bitmap, orig_bitmap; 283 + 284 + if(!parameter) return PLUGIN_ERROR; 285 + 286 + rb = api; 287 + 288 + rb->strcpy(filename, parameter); 289 + 290 + fd = rb->open(filename, O_RDONLY); 291 + if (fd < 0) 292 + { 293 + ppm_error("Couldnt open file: %s, %d", filename, fd); 294 + return PLUGIN_ERROR; 295 + } 296 + 297 + result = read_ppm(fd, &cols, &rows, &maxval); 298 + 299 + rb->close(fd); 300 + if(result == PLUGIN_ERROR) return PLUGIN_ERROR; 301 + 302 + orig_bitmap.width = cols; 303 + orig_bitmap.height = rows; 304 + orig_bitmap.data = (char*)buffer; 305 + 306 + if (cols > LCD_WIDTH || rows > LCD_HEIGHT) 307 + { 308 + if (cols > LCD_WIDTH) { 309 + small_bitmap.width = LCD_WIDTH; 310 + small_bitmap.height = 311 + (int)(((float)LCD_WIDTH / (float)cols) * (float)rows); 312 + 313 + } else { /* rows > LCD_HEIGHT */ 314 + 315 + small_bitmap.width = 316 + (int)(((float)LCD_HEIGHT / (float)rows) * (float)cols); 317 + small_bitmap.height = LCD_HEIGHT; 318 + } 319 + small_bitmap.data = (char*)lcd_buf; 320 + 321 + smooth_resize_bitmap( &orig_bitmap, &small_bitmap ); 322 + 323 + rb->lcd_bitmap((fb_data*)small_bitmap.data, 0, 0, 324 + small_bitmap.width, small_bitmap.height); 325 + } else { 326 + rb->lcd_bitmap((fb_data*)orig_bitmap.data, 0, 0, cols, rows); 327 + } 328 + rb->lcd_update(); 329 + rb->button_get(true); 330 + 331 + return PLUGIN_OK; 332 + } 333 + 334 + #endif
+1
apps/plugins/viewers.config
··· 36 36 sna,viewers/zxbox,12 37 37 tzx,viewers/zxbox,12 38 38 z80,viewers/zxbox,12 39 + ppm,viewers/ppmviewer,2 39 40 *,viewers/properties,- 40 41 colours,apps/text_editor,11 41 42 ssg,games/superdom,-