/* * Trevor's utility to display empeg logos * * Copyright (C) 2003 Trevor Man * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include "hijack.h" inline unsigned long get_long(unsigned char *ptr); inline unsigned int get_short(unsigned char *ptr); int main(int argc, char *argv[]) { int display_fd; int input_fd; caddr_t display; caddr_t input; unsigned long offset; unsigned int frame; unsigned int tmp; unsigned int tmp2; struct stat stat_buf; struct timeval timeout; fprintf(stderr, "EmpView v1.0 - Copyright 2004 - Trevor Man\n"); if (argc != 2) { fprintf(stderr, "%s bmp_file/raw_ani_file\n", argv[0]); return 1; } if ((input_fd = open(argv[1], O_RDONLY)) == -1) { fprintf(stderr, "Unable to open %s for reading.\n", argv[1]); return 1; } if ((display_fd = open("/dev/display", O_RDWR)) == -1) { fprintf(stderr, "Unable to open display.\n"); return 1; } if (fstat(input_fd, &stat_buf) == -1) { fprintf(stderr, "Unable to stat %s\n.", argv[1]); return 1; } if ((input = mmap(0, stat_buf.st_size, PROT_READ, MAP_SHARED, input_fd, 0)) == (caddr_t)-1) { fprintf(stderr, "Unable to map %s\n", argv[1]); return 1; } if ((display = mmap(0, 2048, PROT_READ | PROT_WRITE, MAP_SHARED, display_fd, 0)) == (caddr_t)-1) { fprintf(stderr, "Unable to map display.\n"); return 1; } if (*input == 'G' && *(input + 1) == 'I' && *(input + 2) == 'F') { fprintf(stderr, "GIF format files are not supported currently.\n"); } else if (*(input + 6) == 'J' && *(input + 7) == 'F' && *(input + 8) == 'I' && *(input + 9) == 'F') { fprintf(stderr, "JPEG format files are not supported currently.\n"); } else if (*input == 'B' && *(input + 1) == 'M') { if (get_long(input + 2) != stat_buf.st_size) { fprintf(stderr, "Corrupt BMP file\n"); } else if (get_long(input + 18) != 128 || get_long(input + 22) != 32 || get_short(input + 28) != 24 || get_short(input + 30) != 0) { fprintf(stderr, "Unsupported BMP format. Must be 128x32@24 uncompressed.\n"); } else { for (tmp = 0; tmp < 32; tmp++) { for (tmp2 = 0; tmp2 < 64; tmp2++) { *(display + tmp * 64 + tmp2) = ((*(input + get_long(input + 10) + ((32 - tmp - 1) * 128 + 2 * tmp2) * 3)) & 0x0F) | ((*(input + get_long(input + 10) + ((32 - tmp - 1) * 128 + 2 * tmp2 + 1) * 3)) & 0xF0); } } ioctl(display_fd, _IOW('d', 1, int), 1); ioctl(display_fd, _IO('d', 0)); } } else { ioctl(display_fd, _IOW('d', 1, int), 1); for (frame = 0; ; frame++) { if ((offset = ((unsigned long *)input)[frame]) == 0) break; if (offset + 1024 - 1> stat_buf.st_size) { fprintf(stderr, "Corrupt file. Aborting.\n"); break; } for (tmp = 0; tmp < 2048; tmp += 2) { *(display + tmp) = ((*(input + offset + (tmp / 2)) & 0xc0) >> 2) | ((*(input + offset + (tmp / 2)) & 0x30) >> 4); *(display + tmp + 1) = ((*(input + offset + (tmp / 2)) & 0x0c) << 2) | ((*(input + offset + (tmp / 2)) & 0x03)); } ioctl(display_fd, _IO('d', 0)); timeout.tv_sec = 0; timeout.tv_usec = 1000000 / 12; select(0, NULL, NULL, NULL, &timeout); } } if (munmap(display, 2048) == -1) { fprintf(stderr, "Unable to unmap display.\n"); } if (munmap(input, stat_buf.st_size) == -1) { fprintf(stderr, "Unable to unmap %s.\n", argv[1]); } close(input_fd); close(display_fd); return 0; } inline unsigned long get_long(unsigned char *ptr) { return *ptr | *(ptr + 1) << 8 | *(ptr + 2) << 16 | *(ptr + 3) << 24; } inline unsigned int get_short(unsigned char *ptr) { return *ptr | *(ptr + 1) << 8; }