This is JpegToTiff.m in view mode; [Download] [Up]
// Tabs:3 Indent:3 /* * JpegToTiff.m, JPEG (JFIF) to TIFF converter. * Author: Michael McCulloch * Written for 3.2, January 15, 1994. * * You may freely copy, distribute and reuse the code in this example. * Michael McCulloch disclaims any warranty of any kind, expressed or * implied, as to its fitness for any particular use. */ #import <appkit/appkit.h> #import <libc.h> #import <string.h> #import <stdio.h> #import <jpeg/jinclude.h> #import <setjmp.h> static jmp_buf setjmp_buffer; /* for return to caller */ static external_methods_ptr emethods; /* needed for access to message_parm */ NXBitmapImageRep *tiff = nil; unsigned char *rgb[5]; int rowCount; unsigned char gamtab[256]; // gamma correction table #define IMAX ((1<<8)-1) /* max intensity value */ METHODDEF void trace_message (const char *msgtext) { fprintf(stderr, msgtext, emethods->message_parm[0], emethods->message_parm[1], emethods->message_parm[2], emethods->message_parm[3], emethods->message_parm[4], emethods->message_parm[5], emethods->message_parm[6], emethods->message_parm[7]); fprintf(stderr, "\n"); /* there is no \n in the format string! */ } METHODDEF void error_exit (const char *msgtext) { trace_message(msgtext); /* report the error message */ (*emethods->free_all) (); /* clean up memory allocation & temp files */ longjmp(setjmp_buffer, 1); /* return control to outer routine */ #ifdef DEBUG fprintf(stderr, "Conversion died.\n"); #endif } METHODDEF void output_init (decompress_info_ptr cinfo) /* This routine should do any setup required */ { /* This routine can initialize for output based on the data passed in cinfo. * Useful fields include: * image_width, image_height Pretty obvious, I hope. * data_precision bits per pixel value; typically 8. * out_color_space output colorspace previously requested * color_out_comps number of color components in same * final_out_comps number of components actually output * final_out_comps is 1 if quantize_colors is true, else it is equal to * color_out_comps. * * If you have requested color quantization, the colormap is NOT yet set. * You may wish to defer output initialization until put_color_map is called. */ NXSize pSize={cinfo->image_width, cinfo->image_height}; if (cinfo->jpeg_color_space == CS_GRAYSCALE){ #ifdef DEBUG fprintf(stderr, "CS_GRAYSCALE image type.\n"); #endif tiff = [[NXBitmapImageRep alloc] initDataPlanes:NULL pixelsWide:cinfo->image_width pixelsHigh:cinfo->image_height bitsPerSample:cinfo->data_precision samplesPerPixel:cinfo->color_out_comps hasAlpha:NO isPlanar:NO colorSpace:NX_OneIsWhiteColorSpace bytesPerRow:0 bitsPerPixel:0]; } else if(cinfo->jpeg_color_space == CS_CMYK){ #ifdef DEBUG fprintf(stderr, "CS_CMYK image type.\n"); #endif tiff = [[NXBitmapImageRep alloc] initDataPlanes:NULL pixelsWide:cinfo->image_width pixelsHigh:cinfo->image_height bitsPerSample:cinfo->data_precision samplesPerPixel:cinfo->color_out_comps hasAlpha:NO isPlanar:YES colorSpace:NX_CMYKColorSpace bytesPerRow:0 bitsPerPixel:0]; } else{ #ifdef DEBUG fprintf(stderr, "CS_RGB image type.\n"); #endif tiff = [[NXBitmapImageRep alloc] initDataPlanes:NULL pixelsWide:cinfo->image_width pixelsHigh:cinfo->image_height bitsPerSample:cinfo->data_precision samplesPerPixel:cinfo->color_out_comps hasAlpha:NO isPlanar:YES colorSpace:NX_RGBColorSpace bytesPerRow:0 bitsPerPixel:0]; } #ifdef DEBUG fprintf(stderr, "Data precsn = %d smps/pixel = %d.\n", cinfo->data_precision, cinfo->color_out_comps); #endif /* init bitmap image rep */ [tiff setSize:&pSize]; [tiff getDataPlanes:rgb]; rowCount = 0; } METHODDEF void put_pixel_rows (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data) /* Write some rows of output data */ { register JSAMPROW ptr0, ptr1, ptr2,ptr3; register long col; register int row; if(cinfo->jpeg_color_space == CS_GRAYSCALE){ for (row = 0; row < num_rows; row++) { ptr0 = pixel_data[0][row]; for (col = 0; col < cinfo->image_width; col++) { *(rgb[0]+col+(rowCount*cinfo->image_width)) = gamtab[*ptr0++]; } rowCount++; } } else if(cinfo->jpeg_color_space == CS_CMYK){ for (row = 0; row < num_rows; row++) { ptr0 = pixel_data[0][row]; ptr1 = pixel_data[1][row]; ptr2 = pixel_data[2][row]; ptr3 = pixel_data[3][row]; for (col = 0; col < cinfo->image_width; col++) { *(rgb[0]+col+(rowCount*cinfo->image_width)) = gamtab[*ptr0++]; *(rgb[1]+col+(rowCount*cinfo->image_width)) = gamtab[*ptr1++]; *(rgb[2]+col+(rowCount*cinfo->image_width)) = gamtab[*ptr2++]; *(rgb[3]+col+(rowCount*cinfo->image_width)) = gamtab[*ptr3++]; } rowCount++; } } else{ for (row = 0; row < num_rows; row++) { ptr0 = pixel_data[0][row]; ptr1 = pixel_data[1][row]; ptr2 = pixel_data[2][row]; for (col = 0; col < cinfo->image_width; col++) { *(rgb[0]+col+(rowCount*cinfo->image_width)) = gamtab[*ptr0++]; *(rgb[1]+col+(rowCount*cinfo->image_width)) = gamtab[*ptr1++]; *(rgb[2]+col+(rowCount*cinfo->image_width)) = gamtab[*ptr2++]; } rowCount++; } } } METHODDEF void output_term (decompress_info_ptr cinfo) /* Finish up at the end of the output */ { /* This termination routine may not need to do anything. */ /* Note that the JPEG code will only call it during successful exit; */ /* if you want it called during error exit, you gotta do that yourself. */ } METHODDEF void d_ui_method_selection (decompress_info_ptr cinfo) { /* if grayscale input, force grayscale output; */ /* else leave the output colorspace as set by main routine. */ if (cinfo->jpeg_color_space == CS_GRAYSCALE) cinfo->out_color_space = CS_GRAYSCALE; if(cinfo->jpeg_color_space == CS_CMYK) cinfo->out_color_space = CS_CMYK; /* select output routines */ cinfo->methods->output_init = output_init; cinfo->methods->put_pixel_rows = put_pixel_rows; cinfo->methods->output_term = output_term; } NXBitmapImageRep *convertJPEGToTIFF(const char *imageFile,float gammaFactor, BOOL showMessage) { struct Decompress_info_struct cinfo; struct Decompress_methods_struct dc_methods; struct External_methods_struct e_methods; int i; /* create gamma table */ for(i=0; i<256; i++) gamtab[i] = (IMAX*pow(i/255.0,gammaFactor)+0.5); if ((cinfo.input_file = fopen(imageFile, "rb")) == NULL) { fprintf(stderr, "can't open %s\n", imageFile); return 0; } cinfo.output_file = NULL; /* no actual output file involved */ cinfo.quantize_colors = FALSE; /* no colormap junk, let PS do the dithering */ /* Initialize the system-dependent method pointers. */ cinfo.methods = &dc_methods; /* links to method structs */ cinfo.emethods = &e_methods; /* Here we supply our own error handler; compare to use of standard * error handler in the previous write_JPEG_file example. */ emethods = &e_methods; /* save struct addr for possible access */ e_methods.error_exit = error_exit; /* supply error-exit routine */ e_methods.trace_message = trace_message; /* supply trace-message routine */ e_methods.trace_level = 0; /* default = no tracing */ e_methods.num_warnings = 0; /* no warnings emitted yet */ e_methods.first_warning_level = 0; /* display first corrupt-data warning */ e_methods.more_warning_level = 3; /* but suppress additional ones */ /* prepare setjmp context for possible exit from error_exit */ if (setjmp(setjmp_buffer)) { fclose(cinfo.input_file); return 0; } jselmemmgr(&e_methods); /* select std memory allocation routines */ #ifdef DEBUG fprintf(stderr, "Called jselmemmgr().\n"); #endif dc_methods.d_ui_method_selection = d_ui_method_selection; /* Set up default decompression parameters. */ j_d_defaults(&cinfo, TRUE); #ifdef DEBUG fprintf(stderr, "Called j_d_defaults().\n"); #endif /* Set up to read a JFIF or baseline-JPEG file. */ /* This is the only JPEG file format currently supported. */ jselrjfif(&cinfo); #ifdef DEBUG fprintf(stderr, "Header was read successfully.\n"); #endif /* Here we go! */ jpeg_decompress(&cinfo); #ifdef DEBUG fprintf(stderr, "Image was decompressed.\n"); #endif if(showMessage) fprintf(stderr, "McFilter:JPEGFilter converting %s: %d x %d\n", (strrchr(imageFile,'/')+1), cinfo.image_width, cinfo.image_height); fclose(cinfo.input_file); return tiff; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.