/* * binimg - show binary file as bitmap * (c) 2004, François Revol, revol@free.fr * released under the MIT licence. * compile with: make binimg LDFLAGS='-lbe -ltranslation' */ #include #include #include #include #include #include #include #include #include const char usage[] = "binimg - show binary file as bitmap\n" "Keys:\n" "h\t display this help\n" "arrows\t resize the window\n" "+/-\t offset the file by one byte\n" "PgUp/PgDown\t scroll\n" "1\t display as 8bpp data\n" "4\t display as 32bpp data\n"; class ImgView : public BView { public: ImgView(BRect frame, const char *fname); ~ImgView(); void FrameResized(float w, float h); void AttachedToWindow(); void KeyDown(const char *bytes, int32 numBytes); void UpdateImg(); private: const char *fname; void *data; size_t datasz; BBitmap *bitmap; color_space colspace; int offset; }; ImgView::ImgView(BRect frame, const char *fname) : BView(frame, fname, B_FOLLOW_ALL_SIDES, B_WILL_DRAW|B_FRAME_EVENTS|B_FULL_UPDATE_ON_RESIZE), data(NULL), bitmap(NULL), colspace(B_RGB32), offset(0) { int fd; struct stat st; this->fname = fname; fd = open(fname, O_RDONLY); if (fstat(fd, &st) >= 0) { datasz = (size_t)st.st_size; data = malloc(datasz); if (data) read(fd, data, datasz); } close(fd); } ImgView::~ImgView() { free(data); delete bitmap; } void ImgView::FrameResized(float w, float h) { UpdateImg(); } void ImgView::AttachedToWindow() { UpdateImg(); } void ImgView::KeyDown(const char *bytes, int32 numBytes) { if (numBytes == 1) switch(bytes[0]) { case B_LEFT_ARROW: if (Window()) Window()->ResizeBy(-1, 0); return; case B_RIGHT_ARROW: if (Window()) Window()->ResizeBy(1, 0); return; case B_UP_ARROW: if (Window()) Window()->ResizeBy(0, -1); return; case B_DOWN_ARROW: if (Window()) Window()->ResizeBy(0, 1); return; case '+': offset++; UpdateImg(); Invalidate(Bounds()); return; case '-': offset = MAX(0,offset-1); UpdateImg(); Invalidate(Bounds()); return; case B_PAGE_DOWN: offset += (int)(Bounds().Width()*Bounds().Height()/2); if (data && (offset > (datasz-50))) offset = datasz-50; UpdateImg(); Invalidate(Bounds()); return; case B_PAGE_UP: offset = (int)MAX(0,offset-(Bounds().Width()*Bounds().Height()/2)); UpdateImg(); Invalidate(Bounds()); return; case '1': colspace = B_CMAP8; UpdateImg(); Invalidate(Bounds()); return; case '4': colspace = B_RGB32; UpdateImg(); Invalidate(Bounds()); return; case 'h': { BAlert *alert = new BAlert("binimg info", usage, "Dismiss"); alert->Go(NULL); } return; } BView::KeyDown(bytes, numBytes); } void ImgView::UpdateImg() { delete bitmap; bitmap = NULL; if (data) { if (Window()) { BString str(fname); str << " (" << Bounds().Width() << " x " << Bounds().Height() << ")"; Window()->SetTitle(str.String()); } bitmap = new BBitmap(Bounds(), colspace); memset(bitmap->Bits(), 0xff, bitmap->BitsLength()); memcpy(bitmap->Bits(), ((char *)data)+offset, MIN((datasz-offset),bitmap->BitsLength())); SetViewBitmap(bitmap); } } int main(int argc, char **argv) { BApplication app("application/x-vnd.mmu_man.binimg"); BWindow *win; ImgView *view; BRect r(50,50,150,150); if (argc < 2) { printf("%s file1 [file2 ...]\n", argv[0]); printf(usage); return 1; } for (int i = 1; i < argc; i++) { view = new ImgView(r.OffsetToCopy(0,0), argv[i]); win = new BWindow(r, argv[i], B_TITLED_WINDOW, 0); win->AddChild(view); view->MakeFocus(); win->SetSizeLimits(1.0,1000.0,1.0,1000.0); win->Show(); r.OffsetBy(20,20); } app.Run(); return 0; }