static int /* O - Number of errors */ do_raster_tests(cups_mode_t mode) /* O - Write mode */ { unsigned page, x, y; /* Looping vars */ FILE *fp; /* Raster file */ cups_raster_t *r; /* Raster stream */ cups_page_header2_t header, /* Page header */ expected; /* Expected page header */ unsigned char data[2048]; /* Raster data */ int errors = 0; /* Number of errors */ /* * Test writing... */ printf("cupsRasterOpen(%s): ", mode == CUPS_RASTER_WRITE ? "CUPS_RASTER_WRITE" : mode == CUPS_RASTER_WRITE ? "CUPS_RASTER_WRITE_COMPRESSED" : "CUPS_RASTER_WRITE_PWG"); fflush(stdout); if ((fp = fopen("test.raster", "wb")) == NULL) { printf("FAIL (%s)\n", strerror(errno)); return (1); } if ((r = cupsRasterOpen(fileno(fp), mode)) == NULL) { printf("FAIL (%s)\n", strerror(errno)); fclose(fp); return (1); } puts("PASS"); for (page = 0; page < 4; page ++) { memset(&header, 0, sizeof(header)); header.cupsWidth = 256; header.cupsHeight = 256; header.cupsBytesPerLine = 256; if (page & 1) { header.cupsBytesPerLine *= 2; header.cupsColorSpace = CUPS_CSPACE_CMYK; header.cupsColorOrder = CUPS_ORDER_CHUNKED; header.cupsNumColors = 4; } else { header.cupsColorSpace = CUPS_CSPACE_K; header.cupsColorOrder = CUPS_ORDER_BANDED; header.cupsNumColors = 1; } if (page & 2) { header.cupsBytesPerLine *= 2; header.cupsBitsPerColor = 16; header.cupsBitsPerPixel = (page & 1) ? 64 : 16; } else { header.cupsBitsPerColor = 8; header.cupsBitsPerPixel = (page & 1) ? 32 : 8; } if (cupsRasterWriteHeader2(r, &header)) puts("cupsRasterWriteHeader2: PASS"); else { puts("cupsRasterWriteHeader2: FAIL"); errors ++; } fputs("cupsRasterWritePixels: ", stdout); fflush(stdout); memset(data, 0, header.cupsBytesPerLine); for (y = 0; y < 64; y ++) if (!cupsRasterWritePixels(r, data, header.cupsBytesPerLine)) break; if (y < 64) { puts("FAIL"); errors ++; } else { for (x = 0; x < header.cupsBytesPerLine; x ++) data[x] = (unsigned char)x; for (y = 0; y < 64; y ++) if (!cupsRasterWritePixels(r, data, header.cupsBytesPerLine)) break; if (y < 64) { puts("FAIL"); errors ++; } else { memset(data, 255, header.cupsBytesPerLine); for (y = 0; y < 64; y ++) if (!cupsRasterWritePixels(r, data, header.cupsBytesPerLine)) break; if (y < 64) { puts("FAIL"); errors ++; } else { for (x = 0; x < header.cupsBytesPerLine; x ++) data[x] = (unsigned char)(x / 4); for (y = 0; y < 64; y ++) if (!cupsRasterWritePixels(r, data, header.cupsBytesPerLine)) break; if (y < 64) { puts("FAIL"); errors ++; } else puts("PASS"); } } } } cupsRasterClose(r); fclose(fp); /* * Test reading... */ fputs("cupsRasterOpen(CUPS_RASTER_READ): ", stdout); fflush(stdout); if ((fp = fopen("test.raster", "rb")) == NULL) { printf("FAIL (%s)\n", strerror(errno)); return (1); } if ((r = cupsRasterOpen(fileno(fp), CUPS_RASTER_READ)) == NULL) { printf("FAIL (%s)\n", strerror(errno)); fclose(fp); return (1); } puts("PASS"); for (page = 0; page < 4; page ++) { memset(&expected, 0, sizeof(expected)); expected.cupsWidth = 256; expected.cupsHeight = 256; expected.cupsBytesPerLine = 256; if (mode == CUPS_RASTER_WRITE_PWG) { strlcpy(expected.MediaClass, "PwgRaster", sizeof(expected.MediaClass)); expected.cupsInteger[7] = 0xffffff; } if (page & 1) { expected.cupsBytesPerLine *= 2; expected.cupsColorSpace = CUPS_CSPACE_CMYK; expected.cupsColorOrder = CUPS_ORDER_CHUNKED; expected.cupsNumColors = 4; } else { expected.cupsColorSpace = CUPS_CSPACE_K; expected.cupsColorOrder = CUPS_ORDER_BANDED; expected.cupsNumColors = 1; } if (page & 2) { expected.cupsBytesPerLine *= 2; expected.cupsBitsPerColor = 16; expected.cupsBitsPerPixel = (page & 1) ? 64 : 16; } else { expected.cupsBitsPerColor = 8; expected.cupsBitsPerPixel = (page & 1) ? 32 : 8; } fputs("cupsRasterReadHeader2: ", stdout); fflush(stdout); if (!cupsRasterReadHeader2(r, &header)) { puts("FAIL (read error)"); errors ++; break; } if (memcmp(&header, &expected, sizeof(header))) { puts("FAIL (bad page header)"); errors ++; print_changes(&header, &expected); } fputs("cupsRasterReadPixels: ", stdout); fflush(stdout); for (y = 0; y < 64; y ++) { if (!cupsRasterReadPixels(r, data, header.cupsBytesPerLine)) { puts("FAIL (read error)"); errors ++; break; } if (data[0] != 0 || memcmp(data, data + 1, header.cupsBytesPerLine - 1)) { printf("FAIL (raster line %d corrupt)\n", y); errors ++; break; } } if (y == 64) { for (y = 0; y < 64; y ++) { if (!cupsRasterReadPixels(r, data, header.cupsBytesPerLine)) { puts("FAIL (read error)"); errors ++; break; } for (x = 0; x < header.cupsBytesPerLine; x ++) if (data[x] != (x & 255)) break; if (x < header.cupsBytesPerLine) { printf("FAIL (raster line %d corrupt)\n", y + 64); errors ++; break; } } if (y == 64) { for (y = 0; y < 64; y ++) { if (!cupsRasterReadPixels(r, data, header.cupsBytesPerLine)) { puts("FAIL (read error)"); errors ++; break; } if (data[0] != 255 || memcmp(data, data + 1, header.cupsBytesPerLine - 1)) { printf("fail (raster line %d corrupt)\n", y + 128); errors ++; break; } } if (y == 64) { for (y = 0; y < 64; y ++) { if (!cupsRasterReadPixels(r, data, header.cupsBytesPerLine)) { puts("FAIL (read error)"); errors ++; break; } for (x = 0; x < header.cupsBytesPerLine; x ++) if (data[x] != ((x / 4) & 255)) break; if (x < header.cupsBytesPerLine) { printf("FAIL (raster line %d corrupt)\n", y + 192); errors ++; break; } } if (y == 64) puts("PASS"); } } } } cupsRasterClose(r); fclose(fp); return (errors); }
int main(int argc, char **argv) { FILE *stdlog = NULL; bool borderless = false; char *input_pathname = NULL; char *output_pathname = NULL; int debug = DBG_ALL; int option; int option_index; int render_flags = 0; int printable_width = -1; int printable_height = -1; int rotation = -1; int inkjet = 1; int resolution = 300; int page_backside = 0; int stripe_height = STRIPE_HEIGHT; int concurrent_stripes = (BUFFERED_ROWS / STRIPE_HEIGHT); DF_duplex_t duplex = DF_DUPLEX_MODE_NONE; DF_media_size_t media_size = DF_MEDIA_SIZE_UNKNOWN; output_format_t output_format = OUTPUT_PPM; int testResult = ERROR; double extra_margin_left, extra_margin_right, extra_margin_top, extra_margin_bottom; int padding_options = PAD_NONE; extra_margin_left = extra_margin_right = extra_margin_top = extra_margin_bottom = 0.0f; const char *logfilename = NULL; FILE *imgfile = NULL; FILE *outputfile = NULL; bool monochrome = false; #ifndef EXCLUDE_PCLM bool pclm_test_mode = false; uint8 *pclm_output_buffer = NULL; void *pclmgen_obj= NULL; int outBuffSize = 0; PCLmPageSetup mypage; PCLmPageSetup *page_info = &mypage; memset(page_info, 0, sizeof(PCLmPageSetup)); #endif /* EXCLUDE_PCLM */ //Add pwg definitions #ifndef NO_CUPS cups_raster_t *ras_out = NULL; /* Raster stream */ cups_page_header2_t header_pwg; /* Page header */ #endif /* NO_CUPS */ while ( (option = getopt_long(argc, argv, "i:o:d:l:w:h:f:s:c:m:r:2:p:x:e:buz?v", long_options, &option_index)) != EOF ) { switch(option) { case 'i': input_pathname = optarg; break; case 'o': output_pathname = optarg; break; case 'd': debug = atoi(optarg); break; case 'l': logfilename = optarg; break; case 'b': borderless = true; break; case 'f': render_flags = atoi(optarg); break; case 'm': media_size = atoi(optarg); break; case 'w': printable_width = atoi(optarg); break; case 'h': printable_height = atoi(optarg); break; case 'r': rotation = atoi(optarg); break; case '2': duplex = atoi(optarg); break; case 'z': inkjet = 0; break; case 'x': resolution = atoi(optarg); break; case 'u': page_backside = 1; break; case 'p': output_format = atoi(optarg); break; case 's': stripe_height = atoi(optarg); break; case 'c': concurrent_stripes = atoi(optarg); break; case 'e': padding_options = atoi(optarg) & PAD_ALL; break; case OPTION_EXTRA_MARGIN_LEFT: extra_margin_left = atof(optarg); break; case OPTION_EXTRA_MARGIN_RIGHT: extra_margin_right = atof(optarg); break; case OPTION_EXTRA_MARGIN_TOP: extra_margin_top = atof(optarg); break; case OPTION_EXTRA_MARGIN_BOTTOM: extra_margin_bottom = atof(optarg); break; case OPTION_MONOCHROME: monochrome = true; break; case 'v': #ifndef EXCLUDE_PCLM pclm_test_mode = true; break; #endif /* EXCLUDE_PCLM */ case '?': default: _print_usage(argv[0]); return(0); } /* switch(option) */ } /* while */ // logging to a file? if (logfilename != NULL) { // open the logfile stdlog = fopen(logfilename, "w"); } // set the logging level and output wprint_set_debug_level(debug); wprint_set_stdlog(((stdlog != NULL) ? stdlog : stderr)); { char buffer[4096]; int param; snprintf(buffer, sizeof(buffer), "JOB PARAMETERS:"); for(param = 1; param < argc; param++) { strncat(buffer, " ", sizeof(buffer)); strncat(buffer, argv[param], sizeof(buffer)); } ifprint((DBG_FORCE, "%s", buffer)); } switch(output_format) { #ifndef EXCLUDE_PCLM case OUTPUT_PDF: if (!pclm_test_mode) { padding_options = PAD_ALL; } break; #endif /* EXCLUDE_PCLM */ #ifndef NO_CUPS case OUTPUT_PWG: break; #endif /* NO_CUPS */ case OUTPUT_PPM: break; default: ifprint((DBG_FORCE, "ERROR: output format not supported, switching to PPM")); output_format = OUTPUT_PPM; break; } do { /* if input file is specified at the end of the command line * without the '-f' option, take it */ if (!input_pathname && optind < argc && argv[optind] != NULL) { // coverity[var_assign_var] input_pathname = argv[optind++]; } if (!input_pathname) { ifprint((DBG_FORCE, "ERROR: invalid arguments")); _print_usage(argv[0]); continue; } /* if output file is specified at the end of the command line * without the '-f' option, take it */ if (!output_pathname && optind < argc && argv[optind] != NULL) { // coverity[var_assign_var] output_pathname = argv[optind++]; } if ((media_size != DF_MEDIA_SIZE_UNKNOWN) && (printable_width <= 0) && (printable_height <= 0)) { float margin_top, margin_bottom, margin_left, margin_right; wprint_job_params_t job_params; printer_capabilities_t printer_caps; memset(&job_params, 0, sizeof(wprint_job_params_t)); memset(&printer_caps, 0, sizeof(printer_capabilities_t)); printer_caps.canDuplex = 1; printer_caps.canPrintBorderless = 1; printer_caps.inkjet = inkjet; job_params.media_size = media_size; job_params.pixel_units = resolution; job_params.duplex = duplex, job_params.borderless = borderless; switch(output_format) { #ifndef EXCLUDE_PCLM case OUTPUT_PDF: job_params.pcl_type = PCLm; break; #endif /* EXCLUDE_PCLM */ #ifndef NO_CUPS case OUTPUT_PWG: job_params.pcl_type = PCLPWG; break; #endif /* NO_CUPS */ default: job_params.pcl_type = PCLNONE; break; } printable_area_get_default_margins(&job_params, &printer_caps, &margin_top, &margin_left, &margin_right, &margin_bottom); printable_area_get(&job_params, margin_top, margin_left, margin_right, margin_bottom); printable_width = job_params.printable_area_width; printable_height = job_params.printable_area_height; // mypage.mediaWidthInPixels = printable_width; //mypage.mediaHeightInPixels = printable_height; #ifndef EXCLUDE_PCLM if(margin_left < 0.0f || margin_top < 0.0f) { mypage.mediaWidthOffset=0.0f; mypage.mediaHeightOffset=0.0f; } else { mypage.mediaWidthOffset=margin_left; mypage.mediaHeightOffset=margin_top; } mypage.pageOrigin=top_left; // REVISIT mypage.dstColorSpaceSpefication=deviceRGB; #endif /* EXCLUDE_PCLM */ } #ifndef EXCLUDE_PCLM mypage.stripHeight=stripe_height; if(resolution==300) { mypage.destinationResolution=res300; } else if(resolution==600) { mypage.destinationResolution=res600; } else if(resolution==1200) { mypage.destinationResolution=res1200; } mypage.duplexDisposition=simplex; mypage.mirrorBackside=false; #endif /* EXCLUDE_PCLM */ if ((printable_width <= 0) || (printable_height <= 0)) { ifprint((DBG_FORCE, "ERROR: missing argumetns for dimensions")); _print_usage(argv[0]); continue; } imgfile = fopen(input_pathname, "r"); if (imgfile == NULL) { ifprint((DBG_FORCE, "unable to open input file")); continue; } testResult = OK; outputfile = NULL; if (output_pathname != NULL) { outputfile = fopen(output_pathname, "w"); } else { ifprint((DBG_FORCE, "output file not provided")); } wprint_image_info_t image_info; wprint_image_setup(&image_info, MIME_TYPE_HPIMAGE, &_wprint_ifc); wprint_image_init(&image_info); /* get the image_info of the input file of specified MIME type */ if ( wprint_image_get_info(imgfile, &image_info) == OK ) { if (rotation < 0) { rotation = ROT_0; if ((render_flags & RENDER_FLAG_PORTRAIT_MODE) != 0) { ifprint((DBG_LOG, "_print_page(): portrait mode")); rotation = ROT_0; } else if ((render_flags & RENDER_FLAG_LANDSCAPE_MODE) != 0) { ifprint((DBG_LOG, "_print_page(): landscape mode")); rotation = ROT_90; } else if (wprint_image_is_landscape(&image_info) && ((render_flags & RENDER_FLAG_AUTO_ROTATE) != 0)) { ifprint((DBG_LOG, "_print_page(): auto mode")); rotation = ROT_90; } if ((duplex == DF_DUPLEX_MODE_BOOK) && page_backside && ((render_flags & RENDER_FLAG_ROTATE_BACK_PAGE) != 0) && ((render_flags & RENDER_FLAG_BACK_PAGE_PREROTATED) == 0)) rotation = ((rotation == ROT_0) ? ROT_180 : ROT_270); } } else { ifprint((DBG_FORCE, "unable to process image")); } wprint_image_set_output_properties(&image_info, rotation, printable_width, printable_height, floor(resolution * extra_margin_top), floor(resolution * extra_margin_left), floor(resolution * extra_margin_right), floor(resolution * extra_margin_bottom), render_flags, stripe_height, concurrent_stripes, padding_options); int buff_size = wprint_image_get_output_buff_size(&image_info); unsigned char * buff = (unsigned char *)malloc(buff_size); memset(buff, 0xff, buff_size); int rows_left, num_rows; int output_width = wprint_image_get_width(&image_info); num_rows = rows_left = wprint_image_get_height(&image_info); int bytes_per_row = BYTES_PER_PIXEL(output_width); // process job start switch(output_format) { #ifndef EXCLUDE_PCLM case OUTPUT_PDF: { pclmgen_obj= (void*)CreatePCLmGen(); outBuffSize = 0; PCLmStartJob(pclmgen_obj, (void**)&pclm_output_buffer, &outBuffSize, pclm_test_mode); if (outputfile != NULL) { fwrite((char *)pclm_output_buffer, 1, outBuffSize, outputfile); } break; } #endif /* EXCLUDE_PCLM */ #ifndef NO_CUPS case OUTPUT_PWG: { ras_out = cupsRasterOpen(fileno(outputfile), CUPS_RASTER_WRITE_PWG); break; } #endif /* NO_CUPS */ default: { break; } } // write start page information switch(output_format) { #ifndef EXCLUDE_PCLM case OUTPUT_PDF: { mypage.SourceWidthPixels = output_width; mypage.SourceHeightPixels = num_rows; if (media_size != DF_MEDIA_SIZE_UNKNOWN) { _get_pclm_media_size_name(media_size, (char*)mypage.mediaSizeName); PCLmGetMediaDimensions(pclmgen_obj, mypage.mediaSizeName, &mypage ); } else { strcpy((char*)mypage.mediaSizeName, "CUSTOM"); mypage.mediaWidth = (((float)printable_width * STANDARD_SCALE_FOR_PDF)/(float)resolution); mypage.mediaHeight = (((float)printable_height * STANDARD_SCALE_FOR_PDF)/(float)resolution); mypage.mediaWidthInPixels = printable_width; mypage.mediaHeightInPixels = printable_height; } float standard_scale =(float)resolution/(float)72; page_info->sourceHeight = (float)num_rows/standard_scale; page_info->sourceWidth = (float)output_width/standard_scale; page_info->colorContent=color_content; page_info->srcColorSpaceSpefication=deviceRGB; page_info->compTypeRequested=compressDCT; outBuffSize = 0; PCLmStartPage(pclmgen_obj, page_info, (void**)&pclm_output_buffer, &outBuffSize); if (outputfile != NULL) { fwrite((char *)pclm_output_buffer, 1, outBuffSize, outputfile); } break; } #endif /* EXCLUDE_PCLM */ #ifndef NO_CUPS case OUTPUT_PWG: { _write_header_pwg(ras_out, resolution, image_info, &header_pwg, monochrome); /* * Output the pages... */ ifprint((DBG_LOG, "cupsWidth = %d", header_pwg.cupsWidth)); ifprint((DBG_LOG, "cupsHeight = %d", header_pwg.cupsHeight)); ifprint((DBG_LOG, "cupsBitsPerColor = %d", header_pwg.cupsBitsPerColor)); ifprint((DBG_LOG, "cupsBitsPerPixel = %d", header_pwg.cupsBitsPerPixel)); ifprint((DBG_LOG, "cupsBytesPerLine = %d", header_pwg.cupsBytesPerLine)); ifprint((DBG_LOG, "cupsColorOrder = %d", header_pwg.cupsColorOrder)); ifprint((DBG_LOG, "cupsColorSpace = %d", header_pwg.cupsColorSpace)); break; } #endif /* NO_CUPS */ default: { _write_header(outputfile, output_width, num_rows, monochrome); break; } } int height, nbytes; int image_row = 0; int actual_rows = 0; while(rows_left > 0) { height = MIN(rows_left, stripe_height); nbytes = wprint_image_decode_stripe(&image_info, image_row, &height, buff); if (nbytes > 0) { int rows_returned = (nbytes / bytes_per_row); actual_rows += rows_returned; if (height != rows_returned) { ifprint((DBG_LOG, "LOG: mismatch in reported bytes & height: %d vs %d", height, rows_returned)); } if (monochrome) { int readIndex, writeIndex; for(readIndex = writeIndex = 0; readIndex < nbytes; readIndex += BYTES_PER_PIXEL(1)) { unsigned char gray = SP_GRAY(buff[readIndex + 0], buff[readIndex + 1], buff[readIndex + 2]); buff[writeIndex++] = gray; if (output_format == OUTPUT_PDF) { buff[writeIndex++] = gray; buff[writeIndex++] = gray; } } nbytes = writeIndex; } // write the data switch(output_format) { #ifndef EXCLUDE_PCLM case OUTPUT_PDF: { outBuffSize= 0; PCLmEncapsulate(pclmgen_obj, buff, bytes_per_row, rows_returned, (void**)&pclm_output_buffer, &outBuffSize); if (outputfile != NULL) { fwrite((char *)pclm_output_buffer, 1, outBuffSize, outputfile); } break; } #endif /* EXCLUDE_PCLM */ #ifndef NO_CUPS case OUTPUT_PWG: { if (ras_out != NULL) { cupsRasterWritePixels(ras_out, buff, nbytes); } break; } #endif /* NO_CUPS */ default: { if (outputfile != NULL) { fwrite(buff, 1, nbytes, outputfile); } } } image_row += height; rows_left -= height; } else { if (nbytes < 0) { ifprint((DBG_ERROR, "ERROR: file appears to be corrupted")); } else { ifprint((DBG_ERROR, "LOG: data end with request image_row: %d for %d rows", image_row, MIN(rows_left, stripe_height))); } break; } } if (num_rows != actual_rows) { ifprint((DBG_ERROR, "ERROR: actual image rows: %d", actual_rows)); } // end of page processing switch(output_format) { #ifndef EXCLUDE_PCLM case OUTPUT_PDF: { outBuffSize = 0; PCLmEndPage(pclmgen_obj, (void**)&pclm_output_buffer, &outBuffSize); if (outputfile != NULL) { fwrite((char *)pclm_output_buffer, 1, outBuffSize, outputfile); } break; } #endif /* EXCLUDE_PCLM */ #ifndef NO_CUPS case OUTPUT_PWG: { break; } #endif /* NO_CUPS */ default: { if (num_rows != actual_rows) { _write_header(outputfile, wprint_image_get_width(&image_info), actual_rows, monochrome); break; } break; } } // end of job processing switch(output_format) { #ifndef EXCLUDE_PCLM case OUTPUT_PDF: { outBuffSize = 0; PCLmEndJob(pclmgen_obj, (void**)&pclm_output_buffer, &outBuffSize); if (outputfile != NULL) { fwrite((char *)pclm_output_buffer, 1, outBuffSize, outputfile); } PCLmFreeBuffer(pclmgen_obj, pclm_output_buffer); DestroyPCLmGen(pclmgen_obj); break; } #endif /* EXCLUDE_PCLM */ #ifndef NO_CUPS case OUTPUT_PWG: { break; } #endif /* NO_CUPS */ default: { break; } } wprint_image_cleanup(&image_info); if (buff != NULL) { free(buff); } } while(0); // close the imagefile if (imgfile != NULL) { fclose(imgfile); } // close the output file if (outputfile != NULL) { fclose(outputfile); } //if we use a res stream close it #ifndef NO_CUPS if(ras_out != NULL){ cupsRasterClose(ras_out); } #endif /* NO_CUPS */ // close the logfile if (stdlog != NULL) { fclose(stdlog); } return(testResult); } /* main */
static void write_test(int fd) /* I - File descriptor to write to */ { int page, x, y; /* Looping vars */ int count; /* Number of bytes to set */ cups_raster_t *r; /* Raster stream */ cups_page_header_t header; /* Page header */ unsigned char data[32][8 * TEST_WIDTH]; /* Raster data to write */ /* * Create a combination of random data and repeated data to simulate * text with some whitespace. */ srand(time(NULL)); memset(data, 0, sizeof(data)); for (y = 0; y < 28; y ++) { for (x = rand() & 127, count = (rand() & 15) + 1; x < sizeof(data[0]); x ++, count --) { if (count <= 0) { x += (rand() & 15) + 1; count = (rand() & 15) + 1; if (x >= sizeof(data[0])) break; } data[y][x] = rand(); } } /* * Test write speed... */ if ((r = cupsRasterOpen(fd, CUPS_RASTER_WRITE)) == NULL) { perror("Unable to create raster output stream"); return; } for (page = 0; page < TEST_PAGES; page ++) { memset(&header, 0, sizeof(header)); header.cupsWidth = TEST_WIDTH; header.cupsHeight = TEST_HEIGHT; header.cupsBytesPerLine = TEST_WIDTH; if (page & 1) { header.cupsBytesPerLine *= 4; header.cupsColorSpace = CUPS_CSPACE_CMYK; header.cupsColorOrder = CUPS_ORDER_CHUNKED; } else { header.cupsColorSpace = CUPS_CSPACE_K; header.cupsColorOrder = CUPS_ORDER_BANDED; } if (page & 2) { header.cupsBytesPerLine *= 2; header.cupsBitsPerColor = 16; header.cupsBitsPerPixel = (page & 1) ? 64 : 16; } else { header.cupsBitsPerColor = 8; header.cupsBitsPerPixel = (page & 1) ? 32 : 8; } cupsRasterWriteHeader(r, &header); for (y = 0; y < TEST_HEIGHT; y ++) cupsRasterWritePixels(r, data[y & 31], header.cupsBytesPerLine); } cupsRasterClose(r); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { int fd; /* Raster file */ cups_raster_t *inras, /* Input raster stream */ *outras; /* Output raster stream */ cups_page_header2_t inheader, /* Input raster page header */ outheader; /* Output raster page header */ int y; /* Current line */ unsigned char *line; /* Line buffer */ int page = 0, /* Current page */ page_width, /* Actual page width */ page_height, /* Actual page height */ page_top, /* Top margin */ page_bottom, /* Bottom margin */ page_left, /* Left margin */ linesize, /* Bytes per line */ lineoffset; /* Offset into line */ unsigned char white; /* White pixel */ ppd_file_t *ppd; /* PPD file */ ppd_attr_t *back; /* cupsBackSize attribute */ _ppd_cache_t *cache; /* PPD cache */ _pwg_size_t *pwg_size; /* PWG media size */ _pwg_media_t *pwg_media; /* PWG media name */ int num_options; /* Number of options */ cups_option_t *options = NULL;/* Options */ const char *val; /* Option value */ if (argc < 6 || argc > 7) { puts("Usage: rastertopwg job user title copies options [filename]"); return (1); } else if (argc == 7) { if ((fd = open(argv[6], O_RDONLY)) < 0) { perror("ERROR: Unable to open print file"); return (1); } } else fd = 0; inras = cupsRasterOpen(fd, CUPS_RASTER_READ); outras = cupsRasterOpen(1, CUPS_RASTER_WRITE_PWG); ppd = ppdOpenFile(getenv("PPD")); back = ppdFindAttr(ppd, "cupsBackSide", NULL); num_options = cupsParseOptions(argv[5], 0, &options); ppdMarkDefaults(ppd); cupsMarkOptions(ppd, num_options, options); cache = ppd ? ppd->cache : NULL; while (cupsRasterReadHeader2(inras, &inheader)) { /* * Compute the real raster size... */ page ++; fprintf(stderr, "PAGE: %d %d\n", page, inheader.NumCopies); page_width = (int)(inheader.cupsPageSize[0] * inheader.HWResolution[0] / 72.0); page_height = (int)(inheader.cupsPageSize[1] * inheader.HWResolution[1] / 72.0); page_left = (int)(inheader.cupsImagingBBox[0] * inheader.HWResolution[0] / 72.0); page_bottom = (int)(inheader.cupsImagingBBox[1] * inheader.HWResolution[1] / 72.0); page_top = page_height - page_bottom - inheader.cupsHeight; linesize = (page_width * inheader.cupsBitsPerPixel + 7) / 8; lineoffset = page_left * inheader.cupsBitsPerPixel / 8; /* Round down */ switch (inheader.cupsColorSpace) { case CUPS_CSPACE_W : case CUPS_CSPACE_RGB : case CUPS_CSPACE_SW : case CUPS_CSPACE_SRGB : case CUPS_CSPACE_ADOBERGB : white = 255; break; case CUPS_CSPACE_K : case CUPS_CSPACE_CMYK : case CUPS_CSPACE_DEVICE1 : case CUPS_CSPACE_DEVICE2 : case CUPS_CSPACE_DEVICE3 : case CUPS_CSPACE_DEVICE4 : case CUPS_CSPACE_DEVICE5 : case CUPS_CSPACE_DEVICE6 : case CUPS_CSPACE_DEVICE7 : case CUPS_CSPACE_DEVICE8 : case CUPS_CSPACE_DEVICE9 : case CUPS_CSPACE_DEVICEA : case CUPS_CSPACE_DEVICEB : case CUPS_CSPACE_DEVICEC : case CUPS_CSPACE_DEVICED : case CUPS_CSPACE_DEVICEE : case CUPS_CSPACE_DEVICEF : white = 0; break; default : _cupsLangPrintFilter(stderr, "ERROR", _("Unsupported raster data.")); fprintf(stderr, "DEBUG: Unsupported cupsColorSpace %d on page %d.\n", inheader.cupsColorSpace, page); return (1); } if (inheader.cupsColorOrder != CUPS_ORDER_CHUNKED) { _cupsLangPrintFilter(stderr, "ERROR", _("Unsupported raster data.")); fprintf(stderr, "DEBUG: Unsupported cupsColorOrder %d on page %d.\n", inheader.cupsColorOrder, page); return (1); } if (inheader.cupsBitsPerPixel != 1 && inheader.cupsBitsPerColor != 8 && inheader.cupsBitsPerColor != 16) { _cupsLangPrintFilter(stderr, "ERROR", _("Unsupported raster data.")); fprintf(stderr, "DEBUG: Unsupported cupsBitsPerColor %d on page %d.\n", inheader.cupsBitsPerColor, page); return (1); } memcpy(&outheader, &inheader, sizeof(outheader)); outheader.cupsWidth = page_width; outheader.cupsHeight = page_height; outheader.cupsBytesPerLine = linesize; outheader.cupsInteger[14] = 0; /* VendorIdentifier */ outheader.cupsInteger[15] = 0; /* VendorLength */ if ((val = cupsGetOption("print-content-optimize", num_options, options)) != NULL) { if (!strcmp(val, "automatic")) strlcpy(outheader.OutputType, "Automatic", sizeof(outheader.OutputType)); else if (!strcmp(val, "graphics")) strlcpy(outheader.OutputType, "Graphics", sizeof(outheader.OutputType)); else if (!strcmp(val, "photo")) strlcpy(outheader.OutputType, "Photo", sizeof(outheader.OutputType)); else if (!strcmp(val, "text")) strlcpy(outheader.OutputType, "Text", sizeof(outheader.OutputType)); else if (!strcmp(val, "text-and-graphics")) strlcpy(outheader.OutputType, "TextAndGraphics", sizeof(outheader.OutputType)); else { fprintf(stderr, "DEBUG: Unsupported print-content-type \"%s\".\n", val); outheader.OutputType[0] = '\0'; } } if ((val = cupsGetOption("print-quality", num_options, options)) != NULL) { int quality = atoi(val); /* print-quality value */ if (quality >= IPP_QUALITY_DRAFT && quality <= IPP_QUALITY_HIGH) outheader.cupsInteger[8] = quality; else { fprintf(stderr, "DEBUG: Unsupported print-quality %d.\n", quality); outheader.cupsInteger[8] = 0; } } if ((val = cupsGetOption("print-rendering-intent", num_options, options)) != NULL) { if (!strcmp(val, "absolute")) strlcpy(outheader.cupsRenderingIntent, "Absolute", sizeof(outheader.cupsRenderingIntent)); else if (!strcmp(val, "automatic")) strlcpy(outheader.cupsRenderingIntent, "Automatic", sizeof(outheader.cupsRenderingIntent)); else if (!strcmp(val, "perceptual")) strlcpy(outheader.cupsRenderingIntent, "Perceptual", sizeof(outheader.cupsRenderingIntent)); else if (!strcmp(val, "relative")) strlcpy(outheader.cupsRenderingIntent, "Relative", sizeof(outheader.cupsRenderingIntent)); else if (!strcmp(val, "relative-bpc")) strlcpy(outheader.cupsRenderingIntent, "RelativeBpc", sizeof(outheader.cupsRenderingIntent)); else if (!strcmp(val, "saturation")) strlcpy(outheader.cupsRenderingIntent, "Saturation", sizeof(outheader.cupsRenderingIntent)); else { fprintf(stderr, "DEBUG: Unsupported print-rendering-intent \"%s\".\n", val); outheader.cupsRenderingIntent[0] = '\0'; } } if (inheader.cupsPageSizeName[0] && (pwg_size = _ppdCacheGetSize(cache, inheader.cupsPageSizeName)) != NULL) { strlcpy(outheader.cupsPageSizeName, pwg_size->map.pwg, sizeof(outheader.cupsPageSizeName)); } else { pwg_media = _pwgMediaForSize((int)(2540.0 * inheader.cupsPageSize[0] / 72.0), (int)(2540.0 * inheader.cupsPageSize[1] / 72.0)); if (pwg_media) strlcpy(outheader.cupsPageSizeName, pwg_media->pwg, sizeof(outheader.cupsPageSizeName)); else { fprintf(stderr, "DEBUG: Unsupported PageSize %.2fx%.2f.\n", inheader.cupsPageSize[0], inheader.cupsPageSize[1]); outheader.cupsPageSizeName[0] = '\0'; } } if (inheader.Duplex && !(page & 1) && back && _cups_strcasecmp(back->value, "Normal")) { if (_cups_strcasecmp(back->value, "Flipped")) { if (inheader.Tumble) { outheader.cupsInteger[1] = -1;/* CrossFeedTransform */ outheader.cupsInteger[2] = 1; /* FeedTransform */ outheader.cupsInteger[3] = page_width - page_left - inheader.cupsWidth; /* ImageBoxLeft */ outheader.cupsInteger[4] = page_top; /* ImageBoxTop */ outheader.cupsInteger[5] = page_width - page_left; /* ImageBoxRight */ outheader.cupsInteger[6] = page_height - page_bottom; /* ImageBoxBottom */ } else { outheader.cupsInteger[1] = 1; /* CrossFeedTransform */ outheader.cupsInteger[2] = -1;/* FeedTransform */ outheader.cupsInteger[3] = page_left; /* ImageBoxLeft */ outheader.cupsInteger[4] = page_bottom; /* ImageBoxTop */ outheader.cupsInteger[5] = page_left + inheader.cupsWidth; /* ImageBoxRight */ outheader.cupsInteger[6] = page_height - page_top; /* ImageBoxBottom */ } } else if (_cups_strcasecmp(back->value, "ManualTumble")) { if (inheader.Tumble) { outheader.cupsInteger[1] = -1;/* CrossFeedTransform */ outheader.cupsInteger[2] = -1;/* FeedTransform */ outheader.cupsInteger[3] = page_width - page_left - inheader.cupsWidth; /* ImageBoxLeft */ outheader.cupsInteger[4] = page_bottom; /* ImageBoxTop */ outheader.cupsInteger[5] = page_width - page_left; /* ImageBoxRight */ outheader.cupsInteger[6] = page_height - page_top; /* ImageBoxBottom */ } else { outheader.cupsInteger[1] = 1; /* CrossFeedTransform */ outheader.cupsInteger[2] = 1; /* FeedTransform */ outheader.cupsInteger[3] = page_left; /* ImageBoxLeft */ outheader.cupsInteger[4] = page_top; /* ImageBoxTop */ outheader.cupsInteger[5] = page_left + inheader.cupsWidth; /* ImageBoxRight */ outheader.cupsInteger[6] = page_height - page_bottom; /* ImageBoxBottom */ } } else if (_cups_strcasecmp(back->value, "Rotated")) { if (inheader.Tumble) { outheader.cupsInteger[1] = -1;/* CrossFeedTransform */ outheader.cupsInteger[2] = -1;/* FeedTransform */ outheader.cupsInteger[3] = page_width - page_left - inheader.cupsWidth; /* ImageBoxLeft */ outheader.cupsInteger[4] = page_bottom; /* ImageBoxTop */ outheader.cupsInteger[5] = page_width - page_left; /* ImageBoxRight */ outheader.cupsInteger[6] = page_height - page_top; /* ImageBoxBottom */ } else { outheader.cupsInteger[1] = 1; /* CrossFeedTransform */ outheader.cupsInteger[2] = 1; /* FeedTransform */ outheader.cupsInteger[3] = page_left; /* ImageBoxLeft */ outheader.cupsInteger[4] = page_top; /* ImageBoxTop */ outheader.cupsInteger[5] = page_left + inheader.cupsWidth; /* ImageBoxRight */ outheader.cupsInteger[6] = page_height - page_bottom; /* ImageBoxBottom */ } } else { /* * Unsupported value... */ fprintf(stderr, "DEBUG: Unsupported cupsBackSide \"%s\".\n", back->value); outheader.cupsInteger[1] = 1; /* CrossFeedTransform */ outheader.cupsInteger[2] = 1; /* FeedTransform */ outheader.cupsInteger[3] = page_left; /* ImageBoxLeft */ outheader.cupsInteger[4] = page_top; /* ImageBoxTop */ outheader.cupsInteger[5] = page_left + inheader.cupsWidth; /* ImageBoxRight */ outheader.cupsInteger[6] = page_height - page_bottom; /* ImageBoxBottom */ } } else { outheader.cupsInteger[1] = 1; /* CrossFeedTransform */ outheader.cupsInteger[2] = 1; /* FeedTransform */ outheader.cupsInteger[3] = page_left; /* ImageBoxLeft */ outheader.cupsInteger[4] = page_top; /* ImageBoxTop */ outheader.cupsInteger[5] = page_left + inheader.cupsWidth; /* ImageBoxRight */ outheader.cupsInteger[6] = page_height - page_bottom; /* ImageBoxBottom */ } if (!cupsRasterWriteHeader2(outras, &outheader)) { _cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data.")); fprintf(stderr, "DEBUG: Unable to write header for page %d.\n", page); return (1); } /* * Copy raster data... */ line = malloc(linesize); memset(line, white, linesize); for (y = page_top; y > 0; y --) if (!cupsRasterWritePixels(outras, line, outheader.cupsBytesPerLine)) { _cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data.")); fprintf(stderr, "DEBUG: Unable to write line %d for page %d.\n", page_top - y + 1, page); return (1); } for (y = inheader.cupsHeight; y > 0; y --) { cupsRasterReadPixels(inras, line + lineoffset, inheader.cupsBytesPerLine); if (!cupsRasterWritePixels(outras, line, outheader.cupsBytesPerLine)) { _cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data.")); fprintf(stderr, "DEBUG: Unable to write line %d for page %d.\n", inheader.cupsHeight - y + page_top + 1, page); return (1); } } memset(line, white, linesize); for (y = page_bottom; y > 0; y --) if (!cupsRasterWritePixels(outras, line, outheader.cupsBytesPerLine)) { _cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data.")); fprintf(stderr, "DEBUG: Unable to write line %d for page %d.\n", page_bottom - y + page_top + inheader.cupsHeight + 1, page); return (1); } free(line); } cupsRasterClose(inras); if (fd) close(fd); cupsRasterClose(outras); return (0); }