/* simple example that shows how zfp can be used to compress pgm images */ #include #include #include #include #include #include "zfp.h" int main(int argc, char* argv[]) { double rate = 0; uint nx, ny; uint x, y; char line[0x100]; uchar* image; zfp_field* field; zfp_stream* zfp; bitstream* stream; void* buffer; size_t bytes; size_t size; switch (argc) { case 2: if (sscanf(argv[1], "%lf", &rate) != 1) goto usage; break; default: usage: fprintf(stderr, "Usage: pgm output.pgm\n"); return EXIT_FAILURE; } /* read pgm header */ if (!fgets(line, sizeof(line), stdin) || strcmp(line, "P5\n") || !fgets(line, sizeof(line), stdin) || sscanf(line, "%u%u", &nx, &ny) != 2 || !fgets(line, sizeof(line), stdin) || strcmp(line, "255\n")) { fprintf(stderr, "error opening image\n"); return EXIT_FAILURE; } if ((nx & 3u) || (ny & 3u)) { fprintf(stderr, "image dimensions must be multiples of four\n"); return EXIT_FAILURE; } /* read image data */ image = malloc(nx * ny); if (fread(image, sizeof(*image), nx * ny, stdin) != nx * ny) { fprintf(stderr, "error reading image\n"); return EXIT_FAILURE; } /* create input array */ field = zfp_field_2d(image, zfp_type_int32, nx, ny); /* initialize compressed stream */ zfp = zfp_stream_open(NULL); if (rate < 0) zfp_stream_set_precision(zfp, (uint)floor(0.5 - rate)); else zfp_stream_set_rate(zfp, rate, zfp_type_int32, 2, zfp_false); bytes = zfp_stream_maximum_size(zfp, field); buffer = malloc(bytes); stream = stream_open(buffer, bytes); zfp_stream_set_bit_stream(zfp, stream); zfp_field_free(field); /* compress */ for (y = 0; y < ny; y += 4) for (x = 0; x < nx; x += 4) { uchar ublock[16]; int32 iblock[16]; uint i, j; for (j = 0; j < 4; j++) for (i = 0; i < 4; i++) ublock[i + 4 * j] = image[x + i + nx * (y + j)]; zfp_promote_uint8_to_int32(iblock, ublock, 2); zfp_encode_block_int32_2(zfp, iblock); } zfp_stream_flush(zfp); size = zfp_stream_compressed_size(zfp); fprintf(stderr, "%u compressed bytes (%.2f bps)\n", (uint)size, (double)size * CHAR_BIT / (nx * ny)); /* decompress */ zfp_stream_rewind(zfp); for (y = 0; y < ny; y += 4) for (x = 0; x < nx; x += 4) { int32 iblock[16]; uchar ublock[16]; uint i, j; zfp_decode_block_int32_2(zfp, iblock); zfp_demote_int32_to_uint8(ublock, iblock, 2); for (j = 0; j < 4; j++) for (i = 0; i < 4; i++) image[x + i + nx * (y + j)] = ublock[i + 4 * j]; } zfp_stream_close(zfp); stream_close(stream); free(buffer); /* output reconstructed image */ printf("P5\n"); printf("%u %u\n", nx, ny); printf("255\n"); fwrite(image, sizeof(*image), nx * ny, stdout); free(image); return 0; }