#include #include #include #include int main(int argc, char **argv) { FILE *fin, *fout; int pnm_ver, x_dim, y_dim, max_val = 1; int i, j, len, start, width, from, to; if (argc != 3 && argc != 4 && argc != 5) { fprintf(stderr, "Usage: pnm-select length width [IN.PNM [OUT.PNM]]\n"); exit(1); } if (sscanf(argv[1], "%d", &len) != 1 || len <= 0) { fprintf(stderr, "Incorrect parameter: %s\n", argv[1]); exit(1); } if (sscanf(argv[2], "%d", &width) != 1 || width <= 0) { fprintf(stderr, "Incorrect parameter: %s\n", argv[2]); exit(1); } if (argc > 3 && strcmp(argv[3], "-")) { fin = fopen(argv[3], "rb"); if (fin == 0) { fprintf(stderr, "Can't open %s\n", argv[3]); exit(1); } } else { fin = stdin; } if (fscanf(fin, "P%d%d%d", &pnm_ver, &x_dim, &y_dim) != 3) { fprintf(stderr, "Bad header\n"); exit(1); } if (pnm_ver < 1 || pnm_ver > 6 || x_dim <= 0 || y_dim <= 0) { fprintf(stderr, "Header parameters are out of range\n"); exit(1); } if (pnm_ver == 2 || pnm_ver == 3 || pnm_ver == 5 || pnm_ver == 6) { if (fscanf(fin, "%d", &max_val) != 1 || max_val <= 0 || max_val > 255) { fprintf(stderr, "Bad maximum value\n"); exit(1); } } if (argc > 4 && strcmp(argv[4], "-")) { fout = fopen(argv[4], "wb"); if (fout == 0) { fprintf(stderr, "Can't open %s\n", argv[4]); exit(1); } } else { fout = stdout; } start = y_dim - len; if (start < 0) { start = 0; len = y_dim; } if (width >= x_dim) { from = 0; to = x_dim; } else { from = (x_dim - width) / 2; to = from + width; } if (fprintf(fout, (pnm_ver == 1 || pnm_ver == 4) ? "P%d\n%d %d\n" : "P%d\n%d %d\n%d\n", pnm_ver, width, len, max_val) < 0) { write_error: fprintf(stderr, "Error writing output file\n"); exit(1); } if (pnm_ver == 1 || pnm_ver == 2) { for(j=0; j= start && i >= from && i < to) { if (fprintf(fout, "%d ", c) < 0) goto write_error; } } if (j >= start) { if (fprintf(fout, "\n") < 0) goto write_error; } } } else if (pnm_ver == 4) { int pack_len = (x_dim + 7)/8; int new_pack_len = (width + 7)/8; unsigned char *buf = (unsigned char *)malloc(pack_len + 1); if (!buf) { fprintf(stderr,"malloc(%d) failed\n", pack_len); exit(1); } buf[pack_len] = 0; // for Valgrind for(j = 0; j= start) { int off = from/8; int a = from % 8; int b = 8 - a; for (i = 0; i < new_pack_len; i++) { buf[i] = (buf[i + off] << a) + (buf[i + off + 1] >> b); } if(fwrite(buf, 1, new_pack_len, fout) != new_pack_len) goto write_error; } } free(buf); } else if (pnm_ver == 5 ) { for(j = 0; j= start && i >= from && i < to) { if (putc(c, fout) == EOF) goto write_error; } } } } else { fprintf(stderr,"Unsupported PNM type = %d\n", pnm_ver); exit(1); } if (fin != stdin) fclose(fin); if (fout != stdout) fclose(fout); return 0; }