static int do_image_pgm_ppm_binary(deark *c, lctx *d, struct page_ctx *pg, de_int64 pos1) { struct deark_bitmap *img = NULL; de_int64 rowspan; de_int64 nsamples; // For both input and output de_int64 bytes_per_sample; de_int64 i, j, k; de_int64 pos = pos1; unsigned int samp_ori[3]; de_byte samp_adj[3]; if(fmt_is_ppm(pg->fmt)) nsamples=3; else nsamples=1; if(pg->maxval<=255) bytes_per_sample=1; else bytes_per_sample=2; rowspan = pg->width * nsamples * bytes_per_sample; pg->image_data_len = rowspan * pg->height; img = de_bitmap_create(c, pg->width, pg->height, (int)nsamples); for(j=0; j<pg->height; j++) { for(i=0; i<pg->width; i++) { for(k=0; k<nsamples; k++) { if(bytes_per_sample==1) { samp_ori[k] = de_getbyte(pos++); } else { samp_ori[k] = (unsigned int)de_getbyte(pos++) << 8 ; samp_ori[k] |= (unsigned int)de_getbyte(pos++); } samp_adj[k] = de_scale_n_to_255(pg->maxval, samp_ori[k]); } if(nsamples==1) { de_bitmap_setpixel_gray(img, i, j, samp_adj[0]); } else { de_uint32 clr; clr = DE_MAKE_RGB(samp_adj[0], samp_adj[1], samp_adj[2]); de_bitmap_setpixel_rgb(img, i, j, clr); } } } de_bitmap_write_to_file(img, NULL, 0); de_bitmap_destroy(img); return 1; }
void de_fmtutil_read_atari_palette(deark *c, dbuf *f, i64 pos, u32 *dstpal, i64 ncolors_to_read, i64 ncolors_used, unsigned int flags) { i64 i; unsigned int n; int pal_bits = 0; // 9, 12, or 15. 0 = not yet determined u8 cr, cg, cb; u8 cr1, cg1, cb1; char cbuf[32]; char tmps[64]; const char *s; s = de_get_ext_option(c, "atari:palbits"); if(s) { pal_bits = de_atoi(s); } if(pal_bits==0 && (flags&DE_FLAG_ATARI_15BIT_PAL)) { pal_bits = 15; } if(pal_bits==0) { // Pre-scan the palette, and try to guess whether Atari STE-style 12-bit // colors are used, instead of the usual 9-bit colors. // I don't know the best way to do this. Sometimes the 4th bit in each // nibble is used for extra color detail, and sometimes it just seems to // contain garbage. Maybe the logic should also depend on the file // format, or the number of colors. int bit_3_used = 0; int nibble_3_used = 0; for(i=0; i<ncolors_to_read; i++) { n = (unsigned int)dbuf_getu16be(f, pos + i*2); if(n&0xf000) { nibble_3_used = 1; } if(n&0x0888) { bit_3_used = 1; } } if(bit_3_used && !nibble_3_used) { de_dbg(c, "12-bit palette colors detected"); pal_bits = 12; } } if(pal_bits<12) { // Default to 9 if <12 pal_bits = 9; } else if(pal_bits<15) { pal_bits = 12; } else { pal_bits = 15; } for(i=0; i<ncolors_to_read; i++) { n = (unsigned int)dbuf_getu16be(f, pos + 2*i); if(pal_bits==15) { cr1 = (u8)((n>>6)&0x1c); if(n&0x0800) cr1+=2; if(n&0x8000) cr1++; cg1 = (u8)((n>>2)&0x1c); if(n&0x0080) cg1+=2; if(n&0x4000) cg1++; cb1 = (u8)((n<<2)&0x1c); if(n&0x0008) cb1+=2; if(n&0x2000) cb1++; cr = de_scale_n_to_255(31, cr1); cg = de_scale_n_to_255(31, cg1); cb = de_scale_n_to_255(31, cb1); de_snprintf(cbuf, sizeof(cbuf), "%2d,%2d,%2d", (int)cr1, (int)cg1, (int)cb1); } else if(pal_bits==12) {
static int do_image_pgm_ppm_ascii(deark *c, lctx *d, struct page_ctx *pg, de_int64 pos1) { struct deark_bitmap *img = NULL; de_int64 nsamples; // For both input and output de_int64 pos = pos1; de_int64 xpos, ypos, sampidx; char samplebuf[32]; size_t samplebuf_used; de_byte b; if(fmt_is_ppm(pg->fmt)) nsamples=3; else nsamples=1; img = de_bitmap_create(c, pg->width, pg->height, (int)nsamples); xpos=0; ypos=0; sampidx=0; samplebuf_used=0; while(1) { if(pos >= c->infile->len) break; // end of file if(ypos==(pg->height-1) && xpos>=pg->width) break; // end of image if(ypos>=pg->height) break; b = de_getbyte(pos++); if(is_pnm_whitespace(b)) { if(samplebuf_used>0) { de_int64 v; de_byte v_adj; // Completed a sample samplebuf[samplebuf_used] = '\0'; // NUL terminate for de_atoi64() v = de_atoi64((const char*)samplebuf); v_adj = de_scale_n_to_255(pg->maxval, v); samplebuf_used = 0; if(nsamples>1) { de_bitmap_setsample(img, xpos, ypos, sampidx, v_adj); } else { de_bitmap_setpixel_gray(img, xpos, ypos, v_adj); } sampidx++; if(sampidx>=nsamples) { sampidx=0; xpos++; if(xpos>=pg->width) { xpos=0; ypos++; } } } else { // Skip extra whitespace continue; } } else { // Non-whitespace. Save for later. if(samplebuf_used < sizeof(samplebuf_used)-1) { samplebuf[samplebuf_used++] = b; } } } de_bitmap_write_to_file(img, NULL, 0); de_bitmap_destroy(img); return 1; }