summaryrefslogtreecommitdiff
path: root/apps/plugins/png/png.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/png/png.c')
-rw-r--r--apps/plugins/png/png.c69
1 files changed, 26 insertions, 43 deletions
diff --git a/apps/plugins/png/png.c b/apps/plugins/png/png.c
index 216077767c..8a5d05be9a 100644
--- a/apps/plugins/png/png.c
+++ b/apps/plugins/png/png.c
@@ -1302,7 +1302,7 @@ void LodePNG_decode(LodePNG_Decoder* decoder, unsigned char* in, size_t insize,
1302 /*TODO: check if this works according to the statement in the documentation: "The converter can convert from greyscale input color type, to 8-bit greyscale or greyscale with alpha"*/ 1302 /*TODO: check if this works according to the statement in the documentation: "The converter can convert from greyscale input color type, to 8-bit greyscale or greyscale with alpha"*/
1303if (!(decoder->infoRaw.color.colorType == 2 || decoder->infoRaw.color.colorType == 6) && !(decoder->infoRaw.color.bitDepth == 8)) { decoder->error = 56; return; } 1303if (!(decoder->infoRaw.color.colorType == 2 || decoder->infoRaw.color.colorType == 6) && !(decoder->infoRaw.color.bitDepth == 8)) { decoder->error = 56; return; }
1304 converted_image = (fb_data *)((intptr_t)(memory + 3) & ~3); 1304 converted_image = (fb_data *)((intptr_t)(memory + 3) & ~3);
1305 converted_image_size = FB_DATA_SZ*decoder->infoPng.width*decoder->infoPng.height; 1305 converted_image_size = decoder->infoPng.width*decoder->infoPng.height;
1306 if ((unsigned char *)(converted_image + converted_image_size) >= decoded_image) { decoder->error = OUT_OF_MEMORY; } 1306 if ((unsigned char *)(converted_image + converted_image_size) >= decoded_image) { decoder->error = OUT_OF_MEMORY; }
1307 if (!decoder->error) decoder->error = LodePNG_convert(converted_image, decoded_image, &decoder->infoRaw.color, &decoder->infoPng.color, decoder->infoPng.width, decoder->infoPng.height); 1307 if (!decoder->error) decoder->error = LodePNG_convert(converted_image, decoded_image, &decoder->infoRaw.color, &decoder->infoPng.color, decoder->infoPng.width, decoder->infoPng.height);
1308} 1308}
@@ -1534,6 +1534,15 @@ int show_menu(void) /* return 1 to quit */
1534 return 0; 1534 return 0;
1535} 1535}
1536 1536
1537void draw_image(struct LodePNG_Decoder* decoder)
1538{
1539 rb->lcd_bitmap_part(resized_image, decoder->x, decoder->y, decoder->infoPng.width/ds /*stride*/,
1540 MAX(0, (LCD_WIDTH - (int)decoder->infoPng.width/(int)ds) / 2),
1541 MAX(0, (LCD_HEIGHT - (int)decoder->infoPng.height/(int)ds) / 2),
1542 decoder->infoPng.width/ds - decoder->x,
1543 decoder->infoPng.height/ds - decoder->y);
1544}
1545
1537/* Pan the viewing window right - move image to the left and fill in 1546/* Pan the viewing window right - move image to the left and fill in
1538 the right-hand side */ 1547 the right-hand side */
1539static void pan_view_right(struct LodePNG_Decoder* decoder) 1548static void pan_view_right(struct LodePNG_Decoder* decoder)
@@ -1541,14 +1550,10 @@ static void pan_view_right(struct LodePNG_Decoder* decoder)
1541 int move; 1550 int move;
1542 1551
1543 move = MIN(HSCROLL, decoder->infoPng.width/ds - decoder->x - LCD_WIDTH); 1552 move = MIN(HSCROLL, decoder->infoPng.width/ds - decoder->x - LCD_WIDTH);
1544 if (move > 0 && decoder->infoPng.width/ds > LCD_WIDTH) 1553 if (move > 0)
1545 { 1554 {
1546 decoder->x += move; 1555 decoder->x += move;
1547 rb->lcd_bitmap_part(resized_image, decoder->x, decoder->y, decoder->infoPng.width/ds /*stride*/, 1556 draw_image(decoder);
1548 MAX(0, (LCD_WIDTH - (int)decoder->infoPng.width/(int)ds) / 2),
1549 MAX(0, (LCD_HEIGHT - (int)decoder->infoPng.height/(int)ds) / 2),
1550 MIN(LCD_WIDTH, decoder->infoPng.width/ds),
1551 MIN(LCD_HEIGHT, decoder->infoPng.height/ds));
1552 rb->lcd_update(); 1557 rb->lcd_update();
1553 } 1558 }
1554} 1559}
@@ -1563,11 +1568,7 @@ static void pan_view_left(struct LodePNG_Decoder* decoder)
1563 if (move > 0) 1568 if (move > 0)
1564 { 1569 {
1565 decoder->x -= move; 1570 decoder->x -= move;
1566 rb->lcd_bitmap_part(resized_image, decoder->x, decoder->y, decoder->infoPng.width/ds /*stride*/, 1571 draw_image(decoder);
1567 MAX(0, (LCD_WIDTH - (int)decoder->infoPng.width/(int)ds) / 2),
1568 MAX(0, (LCD_HEIGHT - (int)decoder->infoPng.height/(int)ds) / 2),
1569 MIN(LCD_WIDTH, decoder->infoPng.width/ds),
1570 MIN(LCD_HEIGHT, decoder->infoPng.height/ds));
1571 rb->lcd_update(); 1572 rb->lcd_update();
1572 } 1573 }
1573} 1574}
@@ -1583,11 +1584,7 @@ static void pan_view_up(struct LodePNG_Decoder* decoder)
1583 if (move > 0) 1584 if (move > 0)
1584 { 1585 {
1585 decoder->y -= move; 1586 decoder->y -= move;
1586 rb->lcd_bitmap_part(resized_image, decoder->x, decoder->y, decoder->infoPng.width/ds /*stride*/, 1587 draw_image(decoder);
1587 MAX(0, (LCD_WIDTH - (int)decoder->infoPng.width/(int)ds) / 2),
1588 MAX(0, (LCD_HEIGHT - (int)decoder->infoPng.height/(int)ds) / 2),
1589 MIN(LCD_WIDTH, decoder->infoPng.width/ds),
1590 MIN(LCD_HEIGHT, decoder->infoPng.height/ds));
1591 rb->lcd_update(); 1588 rb->lcd_update();
1592 } 1589 }
1593} 1590}
@@ -1599,14 +1596,10 @@ static void pan_view_down(struct LodePNG_Decoder* decoder)
1599 int move; 1596 int move;
1600 1597
1601 move = MIN(VSCROLL, decoder->infoPng.height/ds - decoder->y - LCD_HEIGHT); 1598 move = MIN(VSCROLL, decoder->infoPng.height/ds - decoder->y - LCD_HEIGHT);
1602 if (move > 0 && decoder->infoPng.height/ds > LCD_HEIGHT) 1599 if (move > 0)
1603 { 1600 {
1604 decoder->y += move; 1601 decoder->y += move;
1605 rb->lcd_bitmap_part(resized_image, decoder->x, decoder->y, decoder->infoPng.width/ds /*stride*/, 1602 draw_image(decoder);
1606 MAX(0, (LCD_WIDTH - (int)decoder->infoPng.width/(int)ds) / 2),
1607 MAX(0, (LCD_HEIGHT - (int)decoder->infoPng.height/(int)ds) / 2),
1608 MIN(LCD_WIDTH, decoder->infoPng.width/ds),
1609 MIN(LCD_HEIGHT, decoder->infoPng.height/ds));
1610 rb->lcd_update(); 1603 rb->lcd_update();
1611 } 1604 }
1612} 1605}
@@ -1765,7 +1758,7 @@ void cb_progress(int current, int total)
1765 1758
1766int pngmem(struct LodePNG_Decoder* decoder, int ds) 1759int pngmem(struct LodePNG_Decoder* decoder, int ds)
1767{ 1760{
1768 return decoder->infoPng.width * decoder->infoPng.height * FB_DATA_SZ / ds; 1761 return (decoder->infoPng.width/ds) * (decoder->infoPng.height/ds) * FB_DATA_SZ;
1769} 1762}
1770 1763
1771/* how far can we zoom in without running out of memory */ 1764/* how far can we zoom in without running out of memory */
@@ -1819,7 +1812,7 @@ fb_data *get_image(struct LodePNG_Decoder* decoder)
1819 previous_size = converted_image_size; 1812 previous_size = converted_image_size;
1820 } 1813 }
1821 1814
1822 size[ds] = decoder->infoPng.width * decoder->infoPng.height * FB_DATA_SZ / ds; 1815 size[ds] = (decoder->infoPng.width/ds) * (decoder->infoPng.height/ds);
1823 1816
1824 /* assign image buffer */ 1817 /* assign image buffer */
1825 if (ds > 1) { 1818 if (ds > 1) {
@@ -1837,7 +1830,7 @@ fb_data *get_image(struct LodePNG_Decoder* decoder)
1837 if ((unsigned char *)(disp[ds] + size[ds]) >= memory_max) { 1830 if ((unsigned char *)(disp[ds] + size[ds]) >= memory_max) {
1838 //rb->splash(HZ, "Out of Memory"); 1831 //rb->splash(HZ, "Out of Memory");
1839 // Still display the original image which is already decoded in RAM 1832 // Still display the original image which is already decoded in RAM
1840 disp[ds] = NULL; 1833 disp[ds] = converted_image;
1841 ds = 1; 1834 ds = 1;
1842 return converted_image; 1835 return converted_image;
1843 } else { 1836 } else {
@@ -1858,10 +1851,9 @@ fb_data *get_image(struct LodePNG_Decoder* decoder)
1858 } 1851 }
1859 } else { 1852 } else {
1860 disp[ds] = converted_image; 1853 disp[ds] = converted_image;
1854 return converted_image;
1861 } 1855 }
1862 1856
1863
1864
1865 previous_disp = disp[ds]; 1857 previous_disp = disp[ds];
1866 previous_size = size[ds]; 1858 previous_size = size[ds];
1867 1859
@@ -1958,6 +1950,7 @@ int load_and_show(char* filename)
1958 rb->lcd_puts(0, 2, print); 1950 rb->lcd_puts(0, 2, print);
1959 rb->lcd_update(); 1951 rb->lcd_update();
1960 } 1952 }
1953
1961 ds_max = max_downscale(&decoder); /* check display constraint */ 1954 ds_max = max_downscale(&decoder); /* check display constraint */
1962 1955
1963 ds = ds_max; /* initials setting */ 1956 ds = ds_max; /* initials setting */
@@ -2009,7 +2002,6 @@ int load_and_show(char* filename)
2009 rb->lcd_update(); 2002 rb->lcd_update();
2010 } 2003 }
2011 2004
2012 do {
2013#if PLUGIN_BUFFER_SIZE >= MIN_MEM 2005#if PLUGIN_BUFFER_SIZE >= MIN_MEM
2014 if (plug_buf && (decoder.error == FILE_TOO_LARGE || decoder.error == OUT_OF_MEMORY || decoder.error == Z_MEM_ERROR)) 2006 if (plug_buf && (decoder.error == FILE_TOO_LARGE || decoder.error == OUT_OF_MEMORY || decoder.error == Z_MEM_ERROR))
2015 { 2007 {
@@ -2073,9 +2065,6 @@ int load_and_show(char* filename)
2073 //else 2065 //else
2074#endif 2066#endif
2075 2067
2076 if (!decoder.error) {
2077 resized_image = get_image(&decoder); /* decode or fetch from cache */
2078 }
2079 if (decoder.error) { 2068 if (decoder.error) {
2080 2069
2081 switch (decoder.error) { 2070 switch (decoder.error) {
@@ -2152,11 +2141,14 @@ int load_and_show(char* filename)
2152 } else if (decoder.error == OUT_OF_MEMORY && entries == 1) { 2141 } else if (decoder.error == OUT_OF_MEMORY && entries == 1) {
2153 return PLUGIN_ERROR; 2142 return PLUGIN_ERROR;
2154 } else { 2143 } else {
2144 file_pt[curfile] = '\0';
2155 return change_filename(direction); 2145 return change_filename(direction);
2156 } 2146 }
2157
2158 } 2147 }
2159 2148
2149 do {
2150 resized_image = get_image(&decoder); /* decode or fetch from cache */
2151
2160 cx = decoder.infoPng.width/ds/2; /* center the view */ 2152 cx = decoder.infoPng.width/ds/2; /* center the view */
2161 cy = decoder.infoPng.height/ds/2; 2153 cy = decoder.infoPng.height/ds/2;
2162 2154
@@ -2171,18 +2163,9 @@ int load_and_show(char* filename)
2171 } 2163 }
2172 2164
2173 rb->lcd_clear_display(); 2165 rb->lcd_clear_display();
2174 2166 draw_image(&decoder);
2175 rb->lcd_bitmap_part(resized_image, decoder.x, decoder.y, decoder.infoPng.width/ds /*stride*/,
2176 MAX(0, (LCD_WIDTH - (int)decoder.infoPng.width/(int)ds) / 2),
2177 MAX(0, (LCD_HEIGHT - (int)decoder.infoPng.height/(int)ds) / 2),
2178 MIN(LCD_WIDTH, decoder.infoPng.width/ds),
2179 MIN(LCD_HEIGHT, decoder.infoPng.height/ds));
2180
2181 rb->lcd_update(); 2167 rb->lcd_update();
2182 2168
2183 //}
2184 //}
2185
2186 /* drawing is now finished, play around with scrolling 2169 /* drawing is now finished, play around with scrolling
2187 * until you press OFF or connect USB 2170 * until you press OFF or connect USB
2188 */ 2171 */