nengel@0: /* nengel@0: * Small jpeg decoder library - testing application nengel@0: * nengel@0: * Copyright (c) 2006, Luc Saillard nengel@0: * All rights reserved. nengel@0: * Redistribution and use in source and binary forms, with or without nengel@0: * modification, are permitted provided that the following conditions are met: nengel@0: * nengel@0: * - Redistributions of source code must retain the above copyright notice, nengel@0: * this list of conditions and the following disclaimer. nengel@0: * nengel@0: * - Redistributions in binary form must reproduce the above copyright notice, nengel@0: * this list of conditions and the following disclaimer in the documentation nengel@0: * and/or other materials provided with the distribution. nengel@0: * nengel@0: * - Neither the name of the author nor the names of its contributors may be nengel@0: * used to endorse or promote products derived from this software without nengel@0: * specific prior written permission. nengel@0: * nengel@0: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" nengel@0: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE nengel@0: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE nengel@0: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE nengel@0: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR nengel@0: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF nengel@0: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS nengel@0: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN nengel@0: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) nengel@0: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE nengel@0: * POSSIBILITY OF SUCH DAMAGE. nengel@0: * nengel@0: */ nengel@0: nengel@0: nengel@0: #include nengel@0: #include nengel@0: #include nengel@0: #include nengel@0: #include nengel@0: nengel@0: #include "tinyjpeg.h" nengel@0: #include "VSs_impl/VSs.h" nengel@0: nengel@0: typedef struct timeval timer; nengel@0: #define TIME(x) gettimeofday(&x, NULL); nengel@0: nengel@0: long timevaldiff(timer *start, timer *finish); nengel@0: nengel@0: static void exitmessage(const char *message) nengel@0: { nengel@0: printf("%s\n", message); nengel@0: exit(0); nengel@0: } nengel@0: nengel@0: static int filesize(FILE *fp) nengel@0: { nengel@0: long pos; nengel@0: fseek(fp, 0, SEEK_END); nengel@0: pos = ftell(fp); nengel@0: fseek(fp, 0, SEEK_SET); nengel@0: return pos; nengel@0: } nengel@0: nengel@0: /** nengel@0: * Save a buffer in 24bits Targa format nengel@0: * (BGR byte order) nengel@0: */ nengel@0: FILE* write_tga_header(const char* filename, int width, int height) { nengel@0: unsigned char targaheader[18]; nengel@0: FILE *F; nengel@0: char temp[1024]; nengel@0: nengel@0: snprintf(temp, sizeof(temp), "%s", filename); nengel@0: nengel@0: memset(targaheader,0,sizeof(targaheader)); nengel@0: nengel@0: targaheader[12] = (unsigned char) (width & 0xFF); nengel@0: targaheader[13] = (unsigned char) (width >> 8); nengel@0: targaheader[14] = (unsigned char) (height & 0xFF); nengel@0: targaheader[15] = (unsigned char) (height >> 8); nengel@0: targaheader[17] = 0x20; /* Top-down, non-interlaced */ nengel@0: targaheader[2] = 2; /* image type = uncompressed RGB */ nengel@0: targaheader[16] = 24; nengel@0: nengel@0: nengel@0: F = fopen(temp, "wb"); nengel@0: fwrite(targaheader, sizeof(targaheader), 1, F); nengel@0: return F; nengel@0: } nengel@0: nengel@0: //todo nengel@0: //#pragma omp task input(*rgb_data) output(*d) inout(*d) nengel@0: void write_tga_task(FILE* fp, int bufferlen, unsigned char* rgb_data, char* d) { nengel@0: nengel@0: // To disable ompss warnings nengel@0: d = d; nengel@0: unsigned char *data = rgb_data + bufferlen - RGB_DEPTH; nengel@0: do nengel@0: { nengel@0: unsigned char c = data[0]; nengel@0: data[0] = data[2]; nengel@0: data[2] = c; nengel@0: data-=RGB_DEPTH; nengel@0: } while (data >= rgb_data); nengel@0: nengel@0: fwrite(rgb_data, 1, bufferlen, fp); nengel@0: } nengel@0: nengel@0: nengel@0: int32 tinyjpegArgTypes[2] = {IN, OUT}; nengel@0: int32 tinyjpegArgSizes[2] = {sizeof(struct jdec_private), sizeof(uint8_t)}; nengel@0: nengel@0: /** nengel@0: * Load one jpeg image, and decompress it, and save the result. nengel@0: */ nengel@0: int convert_one_image(const char *infilename, const char *outfilename) nengel@0: { nengel@0: FILE *fp; nengel@0: unsigned int length_of_file; nengel@0: unsigned int width, height; nengel@0: unsigned char *buf; nengel@0: struct jdec_private *jdec; //for parsing header nengel@0: struct jdec_private **jdec_task; //for decoding mcus nengel@0: uint8_t *rgb_data; nengel@0: int i; nengel@0: int ntasks; nengel@0: nengel@0: /* Load the Jpeg into memory */ nengel@0: fp = fopen(infilename, "rb"); nengel@0: if (fp == NULL) nengel@0: perror("Cannot open image");//exitmessage("Cannot open filename\n"); nengel@0: length_of_file = filesize(fp); nengel@0: buf = (unsigned char *)malloc(length_of_file + 4); nengel@0: if (buf == NULL) nengel@0: exitmessage("Not enough memory for loading file\n"); nengel@0: fread(buf, length_of_file, 1, fp); nengel@0: fclose(fp); nengel@0: nengel@0: /* Decompress it */ nengel@0: jdec = tinyjpeg_init(); nengel@0: if (jdec == NULL) nengel@0: exitmessage("Not enough memory to alloc the structure need for decompressing\n"); nengel@0: nengel@0: if (tinyjpeg_parse_header(jdec, buf, length_of_file)<0) nengel@0: exitmessage(tinyjpeg_get_errorstring()); nengel@0: nengel@0: /* Get the size of the image */ nengel@0: tinyjpeg_get_size(jdec, &width, &height); nengel@0: nengel@0: // RGB stuff nengel@0: rgb_data = (uint8_t *)malloc(width * height * RGB_DEPTH); nengel@0: jdec->components[0] = rgb_data; nengel@0: nengel@0: // this jpeg decoder only supports full MCUs for simplicity nengel@0: ntasks = (jdec->mcus_in_width * jdec->mcus_in_height)/ jdec->restart_interval; nengel@0: jdec_task = (struct jdec_private **) malloc ( ntasks * sizeof(struct jdec_private*)); nengel@0: nengel@0: nengel@0: //VSs setup nengel@0: tinyjpegTaskType = VMS_App__malloc( sizeof(VSsTaskType) ); nengel@0: tinyjpegTaskType->fn = &tinyjpeg_decode_task; nengel@0: tinyjpegTaskType->numCtldArgs = 2; nengel@0: tinyjpegTaskType->numTotalArgs = 2; nengel@0: tinyjpegTaskType->sizeOfArgs = sizeof(tinyjpeg_decode_task_args); nengel@0: tinyjpegTaskType->argTypes = tinyjpegArgTypes; nengel@0: tinyjpegTaskType->argSizes = tinyjpegArgSizes; nengel@0: nengel@0: tinyjpeg_decode_task_args args; nengel@0: nengel@0: fp = write_tga_header(outfilename, width, height); nengel@0: printf("Decoding JPEG image...\n"); nengel@0: for (i=0; i \n"); nengel@0: exit(1); nengel@0: } nengel@0: nengel@0: /* nengel@0: * Calculates the time difference between start and finish in msecs. nengel@0: */ nengel@0: long timevaldiff(timer *start, timer *finish){ nengel@0: long msec; nengel@0: msec = (finish->tv_sec - start->tv_sec)*1000; nengel@0: msec += (finish->tv_usec - start->tv_usec)/1000; nengel@0: return msec; nengel@0: } nengel@0: nengel@0: nengel@0: char *output_filename, *input_filename; nengel@0: /** nengel@0: * Benchmark MAIN nengel@0: */ nengel@0: int main(int argc, char *argv[]) nengel@0: { nengel@0: nengel@0: if (argc < 3) nengel@0: usage(); nengel@0: nengel@0: nengel@0: input_filename = argv[1]; nengel@0: output_filename = argv[2]; nengel@0: nengel@0: VSs__create_seed_slave_and_do_work( &convert_one_image_wrapper, nengel@0: NULL ); nengel@0: nengel@0: nengel@0: nengel@0: return 0; nengel@0: } nengel@0: nengel@0: nengel@0: nengel@0: void convert_one_image_wrapper( void *_params, SlaveVP *animSlv ){ nengel@0: master = animSlv; nengel@0: nengel@0: printf("Input file: %s\nOutput file: %s\n",input_filename,output_filename); nengel@0: nengel@0: convert_one_image(input_filename, output_filename); nengel@0: } nengel@0: