recover.c (3125B)
1#include "raylib.h" 2 3#include <err.h> 4#include <string.h> 5#include <stdio.h> 6#include <stdint.h> 7#include <stdbool.h> 8#include <stdlib.h> 9 10#define BLOCKSIZE 16 11#define BESTN 4 12 13struct block { 14 uint8_t data[BLOCKSIZE]; 15 uint32_t cnt; 16}; 17 18uint8_t * 19read_file(const char *filename, size_t *size) 20{ 21 uint8_t *buf; 22 FILE *f; 23 24 f = fopen(filename, "r"); 25 if (!f) err(1, "fopen"); 26 27 fseek(f, 0, SEEK_END); 28 *size = ftell(f); 29 fseek(f, 0, SEEK_SET); 30 31 buf = malloc(*size); 32 if (!buf) err(1, "malloc"); 33 34 if (!fread(buf, *size, 1, f)) 35 err(1, "fread"); 36 37 fclose(f); 38 39 return buf; 40} 41 42void 43update(struct block *blocks, struct block *bestblocks, 44 size_t *blockslen, uint8_t *img, size_t imglen) 45{ 46 struct block cmp, tmp; 47 size_t tmpcnt; 48 size_t i, k; 49 50 memset(bestblocks, 0, BESTN * sizeof(struct block)); 51 *blockslen = 0; 52 for (i = 0; i < imglen - BLOCKSIZE + 1; i += BLOCKSIZE) { 53 for (k = 0; k < *blockslen; k++) { 54 if (!memcmp(blocks[k].data, &img[i], BLOCKSIZE)) { 55 blocks[k].cnt += 1; 56 break; 57 } 58 } 59 if (k == *blockslen) { 60 memcpy(blocks[k].data, &img[i], BLOCKSIZE); 61 blocks[k].cnt = 1; 62 *blockslen += 1; 63 } 64 65 memcpy(&cmp, &blocks[k], sizeof(struct block)); 66 for (k = 0; k < BESTN; k++) { 67 if (cmp.cnt > bestblocks[k].cnt || !bestblocks[k].cnt) { 68 memcpy(&tmp, &bestblocks[k], sizeof(struct block)); 69 memcpy(&bestblocks[k], &cmp, sizeof(struct block)); 70 memcpy(&cmp, &tmp, sizeof(struct block)); 71 } 72 } 73 } 74} 75 76 77int 78main(int argc, const char **argv) 79{ 80 const int wwidth = 1920; 81 const int wheight = 1080; 82 struct block bestblocks[BESTN]; 83 struct block *blocks; 84 char textbuf[256]; 85 size_t blockslen; 86 size_t imgoff, imglen; 87 size_t width, height; 88 size_t x, y, pos, i; 89 uint8_t *img; 90 91 if (argc < 2) return 1; 92 93 img = read_file(argv[1], &imglen); 94 95 blocks = malloc(imglen / BLOCKSIZE * sizeof(struct block)); 96 if (!blocks) err(1, "malloc"); 97 98 InitWindow(wwidth, wheight, "bmpass"); 99 100 update(blocks, bestblocks, &blockslen, img, imglen); 101 102 width = wwidth; 103 imgoff = 0; 104 while (!WindowShouldClose()) { 105 if (IsKeyDown(KEY_LEFT) && width > 0) 106 width -= 1; 107 else if (IsKeyDown(KEY_RIGHT)) 108 width += 1; 109 else if (IsKeyDown(KEY_DOWN) && imgoff > 0) 110 imgoff -= BLOCKSIZE; 111 else if (IsKeyDown(KEY_UP)) 112 imgoff += BLOCKSIZE; 113 else if (IsKeyDown(KEY_ESCAPE)) 114 break; 115 116 BeginDrawing(); 117 118 ClearBackground(GRAY); 119 120 height = (imglen - imgoff) / width; 121 for (y = 0; y < height; y++) { 122 if (y >= wheight) continue; 123 for (x = 0; x < width; x++) { 124 if (x >= wwidth) continue; 125 pos = (imgoff + y * width + x) 126 / BLOCKSIZE * BLOCKSIZE; 127 if (pos + BLOCKSIZE >= imglen) continue; 128 for (i = 0; i < BESTN; i++) { 129 if (!memcmp(bestblocks[i].data, 130 img + pos, BLOCKSIZE)) 131 break; 132 } 133 if (i != BESTN) 134 DrawPixel(x, wheight - 1 - y, BLACK); 135 else 136 DrawPixel(x, wheight - 1 - y, WHITE); 137 } 138 } 139 140 snprintf(textbuf, sizeof(textbuf), "imgoff %lu", imgoff); 141 DrawText(textbuf, 10, wheight - 40, 20, BLACK); 142 143 snprintf(textbuf, sizeof(textbuf), "width %lu", width); 144 DrawText(textbuf, 10, wheight - 20, 20, BLACK); 145 146 EndDrawing(); 147 } 148 149 CloseWindow(); 150}