long OVTellFunc(void *datasource) { File * file = (File*)datasource; return (long)file->GetPos(); }
void Graphics_::DrawImage(File& f, int x, int y, int scroll, int lines) { //File f; //char s[256]; //sprintf(s,"Draw %d %d %d %d\n",x,y,scroll,lines); //print(s); Img2 hdr; if (!f.Read(&hdr,sizeof(Img2)) || !cmp(hdr.sig,"img2")) return; // Load palette byte palette[512]; int paletteLen = (hdr.colors*2 + 3) & ~3; f.Read(palette+2,paletteLen); // Align to 4 int width = hdr.width; if (lines == 0) lines = hdr.height; int maxy = min(hdr.height,lines) + y; // Skip restart indexes if (hdr.restartInterval) { int restarts = (hdr.height + hdr.restartInterval - 1)/hdr.restartInterval + 1; if (scroll > 0) // { int i = min(scroll/hdr.restartInterval,restarts-1); scroll -= i*hdr.restartInterval; maxy -= i*hdr.restartInterval; f.Skip(i*4); ulong restart; f.Read(&restart,4); f.SetPos(restart); } else f.Skip(restarts*4); } // Skip restart intervals if (maxy > 320) maxy = 320; LCD.SetBounds(x,y,hdr.width,maxy-y); // TODO: clip byte format = hdr.format; if (format & 0x80) { f.SetPos(512 + ((long)scroll)*512); while (y < maxy) { // 512 bytes in buffer int count; const byte* b = f.GetBuffer(&count); LCD.Blit(b,width); f.Skip(512); y++; } return; } // Run length compressed // int left = x; // TODO YUCK int miny = y; y -= scroll; long lastPos = 0; while (y < maxy) { bool clip = y < miny; // Repeat line? byte repeat = 1; long pos = f.GetPos(); lastPos = pos; if (f.ReadByte() == 0xFF) { repeat = f.ReadByte(); pos += 2; repeat = min(repeat,maxy-y); // TODO BUG } // decode a line while (repeat--) { y++; f.SetPos(pos); // Encoder prevents backing up to previous sector x = 0; while (x < width) { int n = f.ReadByte(); bool ex = (n & 0x80) != 0; n &= 0x7F; if (n > 120) { if (n == 126) // skip { x += f.ReadByte(); if (!clip) { #if 0 TODO BUGBUG if (x == width) LCDSetGRAM(left,y); else LCDSetGRAM(left+x,y-1); #endif } continue; } n = ((n-121) << 8) | f.ReadByte(); } x += n; if (x > width) { for (;;) { } } int count; if (ex) { // explicit if (format == 8) { while (n) { const byte* b = f.GetBuffer(&count); count = min(count,n); if (!clip) LCD.BlitIndexed(b,palette,count); f.Skip(count); // Always works within buffer n -= count; } } else { while (n) { const byte* b = f.GetBuffer(&count); if (count == 1) { int color = (f.ReadByte() << 8) | f.ReadByte(); // Wrap around if (!clip) LCD.Fill(color,1); } else { count >>= 1; count = min(count,n); if (!clip) LCD.Blit(b,count); f.Skip(count<<1); } n -= count; } } } else { // run byte a = f.ReadByte(); byte b; if (format == 8) { b = palette[a*2+1]; a = palette[a*2]; } else b = f.ReadByte(); if (!clip) LCD.Fill((a << 8) | b,n); } }