?? zdjpeg.c
字號:
// zJpegInit( vMem, pMem ); zJpegInit( APP_PHY_MEMORY + vMem, APP_PHY_MEMORY + pMem ); /* * Override the default JPEG error handling. [Note, this functionality may * change in future releases!] */ cinfo.err = zJpegStdError(&errorHandler.pub); errorHandler.pub.error_exit = zdjpegErrorExit; /* Establish the setjmp return context */ if (setjmp(errorHandler.setjmp_buffer)) { zJpegFinishDecompress(&cinfo); return 0; } /* Scan command line to find file names. */ /* It is convenient to use just one switch-parsing routine, but the switch * values read here are ignored; we will rescan the switches after opening * the input file. * (Exception: tracing level set here controls verbosity for COM markers * found during jpeg_read_header...) */ file_index = parse_switches(&cinfo, argc, argv, 0, FALSE); /* * This semaphore syncs this command line utility to the asynchronous decode */ sem_init(&done, 0, 0); /* * Initialize 3D graphics */ display_init(); /* * Now decide if we are in one-shot or slideshow mode and proceed accordingly */ if (slideshow == FALSE && play == FALSE && tile == FALSE && outfilename == NULL) { /* * Initialize the JPEG decompression object */ if (zJpegCreateDecompress( &cinfo ) != EXIT_SUCCESS) { fprintf(stderr, "%s: can't create decompression object\n", progname); exit(EXIT_FAILURE); } /* * At this point pZSP which is the ZEVIO specific 'cinfo' extension can be * initialized. The intention is that 'cinfo' remains as standard and all * extensions use the existing 'client_data' pointer to user extensions */// pZSP = (struct zjpeg_command *)cinfo.client_data; if (file_index < argc) { if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) { fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]); exit(EXIT_FAILURE); } } else { fprintf(stderr, "%s: must name one input and one output file\n", progname); usage(); } if (zJpegOKToDecode(&cinfo, input_file) == JPEG_NOK_TO_DECODE) { printf("Unsupported Image Type\n"); zJpegReleaseDecompress(&cinfo); fclose(input_file); return 1; } if (cinfo.err->trace_level) { timSet.it_interval.tv_sec = INTERVAL_TIME; timSet.it_interval.tv_usec = 0; timSet.it_value.tv_sec = INTERVAL_TIME; timSet.it_value.tv_usec = 0; assert(!setitimer(ITIMER_REAL, &timSet, NULL)); } /* * Specify data source for decompression. File and memory sources are * supported although memory does not make any sense in the context of a * command line utility... */ zJpegStdioSrc(&cinfo, input_file); /* * Read file header which sets the default decompression parameters. At this * point the ZEVIO decoder can check for an embedded thumbnail, see the logic * below for details... */ if (zJpegReadHeader(&cinfo, thumbnail, &thumbnailFound) == JPEG_NOK_TO_DECODE) { printf("Unsupported Image Type\n"); zJpegFinishDecompress(&cinfo); zJpegReleaseDecompress(&cinfo); fclose(input_file); return 1; } if(thumbnail == TRUE && thumbnailFound == FALSE) { fprintf(stderr, "%s: no thumbnail present\n", progname); zJpegFinishDecompress(&cinfo); rewind(input_file); zJpegStdioSrc(&cinfo, input_file); zJpegReadHeader(&cinfo, FALSE, &thumbnailFound); oWidth = 160; oHeight = 120; } if (thumbnail == TRUE) { oWidth = 160; oHeight = 120; } /* * Adjust default decompression parameters by re-parsing the options. In a * real application the decode parameters must be set after reading the * header */ file_index = parse_switches( &cinfo, argc, argv, 0, TRUE ); /* * Scale the image to fit the desired output size. Here we always scale to * match aspect ratio and maximum 800x600 */ zJpegSetOutputSize( &cinfo, &oWidth, &oHeight, SCALE_MAX ); printf("SetOutputSize: %d x %d\n", oWidth, oHeight); /* * (void*) gpuBuf.pBase = physical address to top left corner of buffer * (unsigned short*) gpuBuf.vBase = virtual address to top left corner of buffer */ GPU_Factory_Request(ZV_GBUF_FULL_SCREEN,&gpuBuf); /* * Start decompressor, the callback and memory pointers for the output * buffer are passed as parameters */ (void) zJpegStartDecompress(&cinfo, freeInputBuffer, 0, gpuBuf.vBase, (unsigned long)gpuBuf.pBase); // Buffer assigned internally for now /* * Pend on callback indicating decode complete */ sem_wait(&done); /* * Decode time is captured before writing out the file which is subject to * NFS delays. Of course the input and swap file are also plagued by NFS * but at least one source of uncertainty is removed... */ if (cinfo.err->trace_level) { assert(!getitimer(ITIMER_REAL, &timGet1)); } assert(oWidth <= OUTPUT_W); assert(oHeight <= OUTPUT_H); /* * Draw LCD display */ GPU_Factory_BindTexture(&gpuBuf); display_pixels( (void *)gpuBuf.vBase, (unsigned short*)gpuVMem, gpuBuf.offset ); if (cinfo.err->trace_level) { assert(!getitimer(ITIMER_REAL, &timGet2)); } /* * Write the image out to the specified file in PPM format. Output width and * output height are constrained if incorrct scaling selection could cause a * memory access problem, any image is capped at 800*600 pixels * * NOTE : Writing a file here totally screws up the presentation time value * but currently drawing to 3D when the image is in GPU memory (not system) * corrupts the decode results so it is here or never! */ /* * Tidy up after decode of a single image, this should be used by any * application */ zJpegReleaseDecompress(&cinfo); /* * Decode & presentation run time output */ if (cinfo.err->trace_level) { zJpegInstrumentation result; zJpegGetInstrumentation( &cinfo, &result ); printf("\n%d %u.%ums [%d] %u.%ums [%d] %d %dx%d %dx%d %dx%d\n", result.ppPackets, result.zspTimer0ms, result.zspTimer0hus, result.zspTimer0oflow, result.zspTimer1ms, result.zspTimer1hus, result.zspTimer1oflow, result.chromaType, result.imageWidth, result.imageHeight, result.outputWidth, result.outputHeight, result.displayWidth, result.displayHeight); time = INTERVAL_TIME*1000000 - (timGet1.it_value.tv_sec * 1000000 + timGet1.it_value.tv_usec); if (time <= 0) printf("Task Timer Elapsed...\n"); else printf("[D] %ld.%02lds ", time/1000000, (time%1000000)/10000); time = INTERVAL_TIME*1000000 - (timGet2.it_value.tv_sec * 1000000 + timGet2.it_value.tv_usec); if (time <= 0) printf("Task Timer Elapsed...\n"); else printf("[P] %ld.%02lds for %s\n", time/1000000, (time%1000000)/10000, argv[file_index]); } fclose(input_file); GPU_Factory_Release(&gpuBuf); /* * The default behavior is to leave the image visible but this obscures the * directFB plane, there is a command line option to delay for 'N' seconds then * clear the image. */ if (presentationDelay) { sleep(presentationDelay); zevio2d_disable_3dscr(); } } else if (outfilename) { /* * This path implements an encode option. It encodes a JPEG with an * embedded thumbnail. Right now the method used is VERY crude, the image * is decoded and encoded twice, once for thumbnail and the second time for * display. Going forward there are much better ways to do this, e.g. * copying the thumbnail from the original image if there are no changes * such as cropping or in the more general case scaling a resulting display * size image to thumbnail size before encoding, much faster than a double * decode but another PP step to implement. * * Also no EXIF is transferred over, that will almost certainly be required * in the future. */ unsigned char *header; FILE *tempFile; unsigned int length, orientation; /* * Step 1 - Decode Thumbnail to a discrete file. To differentiate the * thumbnails and bypass ZSP PP (necessary for this low rent solution) the * thumbnail is going to be generated at 200*150. */ if (zJpegCreateDecompress( &cinfo ) != EXIT_SUCCESS) { fprintf(stderr, "%s: can't create decompression object\n", progname); exit(EXIT_FAILURE); } if (file_index < argc) { if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) { fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]); exit(EXIT_FAILURE); } } else { fprintf(stderr, "%s: must name one input and one output file\n", progname); usage(); } GPU_Factory_Request(ZV_GBUF_FULL_SCREEN,&gpuBuf); zJpegStdioSrc(&cinfo, input_file); zJpegReadHeader(&cinfo, FALSE, &thumbnailFound); oWidth = 200; oHeight = 150; orientation = zJpegGetOrientation( &cinfo ); zJpegSetOutputSize( &cinfo, &oWidth, &oHeight, SCALE_MAX ); rgbBuffer = malloc(800 * 3 * 2); assert(rgbBuffer); zJpegSetRGBbuffer( &cinfo, rgbBuffer ); encodeStart( &cinfo, "temp", oWidth, oHeight, 80 ); (void) zJpegStartDecompress(&cinfo, freeInputBuffer, 0, gpuBuf.vBase, (unsigned long)gpuBuf.pBase); // Buffer assigned internally for now sem_wait(&done); encodeEnd(); zJpegFinishDecompress(&cinfo);// zJpegReleaseDecompress(&cinfo);printf("Thumb complete\n"); /* * Step 2 - Read back the temporary file into a memory buffer and determine * its length. The image is read after sufficient space for the APP1/IFD * header so that the marker can be written in a single go */ header = (unsigned char *)malloc(16384); assert(header); tempFile = fopen("temp.jpg", "rb"); assert(tempFile); length = fread(header + 74, 1, 16384-74, tempFile); assert(length); fclose(tempFile);printf("Thumb read\n"); if (length == 16384-74) { printf("Warning JPEG Thumbnail too big!\n"); } header[ 0] = 'E'; // Exif marker header[ 1] = 'x'; header[ 2] = 'i'; header[ 3] = 'f'; header[ 4] = 0x00; header[ 5] = 0x00; header[ 6] = 0x49; // Indicates little Endian TIFF, start of TIFF header[ 7] = 0x49; header[ 8] = 0x2A; // TIFF Magic Number header[ 9] = 0x00; header[10] = 0x08; // Offset from start of TIFF to IFD0 header[11] = 0x00; header[12] = 0x00; header[13] = 0x00; header[14] = 0x01; // IFD0 Entry Count header[15] = 0x00; header[16] = 0x12; // Orientation Tag header[17] = 0x01; header[18] = 0x03; header[19] = 0x00; header[20] = 0x01; header[21] = 0x00; header[22] = 0x00; header[23] = 0x00; header[24] = orientation; // Orientation Value header[25] = 0x00; header[26] = 0x00; header[27] = 0x00; header[28] = 0x1A; // Offset from start of TIFF to IFD1 header[29] = 0x00; header[30] = 0x00; header[31] = 0x00;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -