annotate VSs_tinyjpeg/loadjpeg.c @ 4:62350c40504f

running in sequential mode
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Mon, 20 Aug 2012 16:56:27 +0200
parents 42d636fee562
children
rev   line source
nengel@0 1 /*
nengel@0 2 * Small jpeg decoder library - testing application
nengel@0 3 *
nengel@0 4 * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
nengel@0 5 * All rights reserved.
nengel@0 6 * Redistribution and use in source and binary forms, with or without
nengel@0 7 * modification, are permitted provided that the following conditions are met:
nengel@0 8 *
nengel@0 9 * - Redistributions of source code must retain the above copyright notice,
nengel@0 10 * this list of conditions and the following disclaimer.
nengel@0 11 *
nengel@0 12 * - Redistributions in binary form must reproduce the above copyright notice,
nengel@0 13 * this list of conditions and the following disclaimer in the documentation
nengel@0 14 * and/or other materials provided with the distribution.
nengel@0 15 *
nengel@0 16 * - Neither the name of the author nor the names of its contributors may be
nengel@0 17 * used to endorse or promote products derived from this software without
nengel@0 18 * specific prior written permission.
nengel@0 19 *
nengel@0 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
nengel@0 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
nengel@0 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
nengel@0 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
nengel@0 24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
nengel@0 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
nengel@0 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
nengel@0 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
nengel@0 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
nengel@0 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
nengel@0 30 * POSSIBILITY OF SUCH DAMAGE.
nengel@0 31 *
nengel@0 32 */
nengel@0 33
nengel@0 34
nengel@0 35 #include <stdio.h>
nengel@0 36 #include <stdint.h>
nengel@0 37 #include <stdlib.h>
nengel@0 38 #include <string.h>
nengel@0 39 #include <sys/time.h>
nengel@0 40
nengel@0 41 #include "tinyjpeg.h"
nengel@0 42 #include "VSs_impl/VSs.h"
nengel@0 43
nengel@0 44 typedef struct timeval timer;
nengel@0 45 #define TIME(x) gettimeofday(&x, NULL);
nengel@0 46
nengel@0 47 long timevaldiff(timer *start, timer *finish);
nengel@0 48
nengel@0 49 static void exitmessage(const char *message)
nengel@0 50 {
nengel@0 51 printf("%s\n", message);
nengel@0 52 exit(0);
nengel@0 53 }
nengel@0 54
nengel@0 55 static int filesize(FILE *fp)
nengel@0 56 {
nengel@0 57 long pos;
nengel@0 58 fseek(fp, 0, SEEK_END);
nengel@0 59 pos = ftell(fp);
nengel@0 60 fseek(fp, 0, SEEK_SET);
nengel@0 61 return pos;
nengel@0 62 }
nengel@0 63
nengel@0 64 /**
nengel@0 65 * Save a buffer in 24bits Targa format
nengel@0 66 * (BGR byte order)
nengel@0 67 */
nengel@0 68 FILE* write_tga_header(const char* filename, int width, int height) {
nengel@0 69 unsigned char targaheader[18];
nengel@0 70 FILE *F;
nengel@0 71 char temp[1024];
nengel@0 72
nengel@0 73 snprintf(temp, sizeof(temp), "%s", filename);
nengel@0 74
nengel@0 75 memset(targaheader,0,sizeof(targaheader));
nengel@0 76
nengel@0 77 targaheader[12] = (unsigned char) (width & 0xFF);
nengel@0 78 targaheader[13] = (unsigned char) (width >> 8);
nengel@0 79 targaheader[14] = (unsigned char) (height & 0xFF);
nengel@0 80 targaheader[15] = (unsigned char) (height >> 8);
nengel@0 81 targaheader[17] = 0x20; /* Top-down, non-interlaced */
nengel@0 82 targaheader[2] = 2; /* image type = uncompressed RGB */
nengel@0 83 targaheader[16] = 24;
nengel@0 84
nengel@0 85
nengel@0 86 F = fopen(temp, "wb");
nengel@0 87 fwrite(targaheader, sizeof(targaheader), 1, F);
nengel@0 88 return F;
nengel@0 89 }
nengel@0 90
nengel@3 91 typedef struct{
nengel@3 92 unsigned char* rgb_data;
nengel@3 93 char* d;
nengel@3 94 FILE* fp;
nengel@3 95 int bufferlen;
nengel@4 96 } write_tga_task_args;
nengel@3 97
nengel@3 98 VSsTaskType *write_tga_taskType;
nengel@3 99
nengel@3 100 int32 write_tga_taskArgTypes[2] = {IN, INOUT};
nengel@3 101 int32 write_tga_taskArgSizes[2] = {sizeof(unsigned char), sizeof(char)};
nengel@3 102
nengel@0 103 //#pragma omp task input(*rgb_data) output(*d) inout(*d)
nengel@3 104 void write_tga_task(void *_data, SlaveVP *animatingSlv ) {
nengel@3 105
nengel@4 106 write_tga_task_args* args2 = (write_tga_task_args*) _data;
nengel@4 107 FILE* fp = args2->fp;
nengel@4 108 int bufferlen = args2->bufferlen;
nengel@4 109 unsigned char* rgb_data = args2->rgb_data;
nengel@4 110 char* d = args2->d;
nengel@3 111
nengel@0 112 // To disable ompss warnings
nengel@0 113 d = d;
nengel@0 114 unsigned char *data = rgb_data + bufferlen - RGB_DEPTH;
nengel@0 115 do
nengel@0 116 {
nengel@0 117 unsigned char c = data[0];
nengel@0 118 data[0] = data[2];
nengel@0 119 data[2] = c;
nengel@0 120 data-=RGB_DEPTH;
nengel@0 121 } while (data >= rgb_data);
nengel@0 122
nengel@0 123 fwrite(rgb_data, 1, bufferlen, fp);
nengel@4 124 VSs__end_task( animatingSlv );
nengel@0 125 }
nengel@0 126
nengel@0 127
nengel@0 128 int32 tinyjpegArgTypes[2] = {IN, OUT};
nengel@0 129 int32 tinyjpegArgSizes[2] = {sizeof(struct jdec_private), sizeof(uint8_t)};
nengel@0 130
nengel@0 131 /**
nengel@0 132 * Load one jpeg image, and decompress it, and save the result.
nengel@0 133 */
nengel@0 134 int convert_one_image(const char *infilename, const char *outfilename)
nengel@0 135 {
nengel@0 136 FILE *fp;
nengel@0 137 unsigned int length_of_file;
nengel@0 138 unsigned int width, height;
nengel@0 139 unsigned char *buf;
nengel@0 140 struct jdec_private *jdec; //for parsing header
nengel@0 141 struct jdec_private **jdec_task; //for decoding mcus
nengel@0 142 uint8_t *rgb_data;
nengel@0 143 int i;
nengel@0 144 int ntasks;
nengel@0 145
nengel@0 146 /* Load the Jpeg into memory */
nengel@0 147 fp = fopen(infilename, "rb");
nengel@0 148 if (fp == NULL)
nengel@0 149 perror("Cannot open image");//exitmessage("Cannot open filename\n");
nengel@0 150 length_of_file = filesize(fp);
nengel@2 151 buf = (unsigned char *)VMS_App__malloc(length_of_file + 4);
nengel@0 152 if (buf == NULL)
nengel@0 153 exitmessage("Not enough memory for loading file\n");
nengel@0 154 fread(buf, length_of_file, 1, fp);
nengel@0 155 fclose(fp);
nengel@0 156
nengel@0 157 /* Decompress it */
nengel@0 158 jdec = tinyjpeg_init();
nengel@0 159 if (jdec == NULL)
nengel@0 160 exitmessage("Not enough memory to alloc the structure need for decompressing\n");
nengel@0 161
nengel@0 162 if (tinyjpeg_parse_header(jdec, buf, length_of_file)<0)
nengel@0 163 exitmessage(tinyjpeg_get_errorstring());
nengel@0 164
nengel@0 165 /* Get the size of the image */
nengel@0 166 tinyjpeg_get_size(jdec, &width, &height);
nengel@0 167
nengel@0 168 // RGB stuff
nengel@2 169 rgb_data = (uint8_t *)VMS_App__malloc(width * height * RGB_DEPTH);
nengel@0 170 jdec->components[0] = rgb_data;
nengel@0 171
nengel@0 172 // this jpeg decoder only supports full MCUs for simplicity
nengel@0 173 ntasks = (jdec->mcus_in_width * jdec->mcus_in_height)/ jdec->restart_interval;
nengel@2 174 jdec_task = (struct jdec_private **) VMS_App__malloc ( ntasks * sizeof(struct jdec_private*));
nengel@0 175
nengel@0 176
nengel@0 177 //VSs setup
nengel@0 178 tinyjpegTaskType = VMS_App__malloc( sizeof(VSsTaskType) );
nengel@0 179 tinyjpegTaskType->fn = &tinyjpeg_decode_task;
nengel@0 180 tinyjpegTaskType->numCtldArgs = 2;
nengel@0 181 tinyjpegTaskType->numTotalArgs = 2;
nengel@0 182 tinyjpegTaskType->sizeOfArgs = sizeof(tinyjpeg_decode_task_args);
nengel@0 183 tinyjpegTaskType->argTypes = tinyjpegArgTypes;
nengel@0 184 tinyjpegTaskType->argSizes = tinyjpegArgSizes;
nengel@0 185
nengel@0 186 tinyjpeg_decode_task_args args;
nengel@0 187
nengel@0 188 fp = write_tga_header(outfilename, width, height);
nengel@0 189 printf("Decoding JPEG image...\n");
nengel@0 190 for (i=0; i<ntasks; i++){
nengel@0 191 jdec_task[i] = create_jdec_priv_task(jdec, i);
nengel@0 192
nengel@0 193 args.priv = jdec_task[i];
nengel@0 194 args.context = rgb_data+i*width*RGB_DEPTH*MCU_Y_STRIDE;
seanhalle@1 195 VSs__submit_task(tinyjpegTaskType, &args, seedSlv);
nengel@0 196
nengel@0 197 }
nengel@0 198
nengel@3 199 write_tga_taskType = VMS_App__malloc( sizeof(VSsTaskType) );
nengel@3 200 write_tga_taskType->fn = &write_tga_task;
nengel@3 201 write_tga_taskType->numCtldArgs = 2;
nengel@3 202 write_tga_taskType->numTotalArgs = 4;
nengel@3 203 write_tga_taskType->sizeOfArgs = sizeof(write_tga_task_args);
nengel@3 204 write_tga_taskType->argTypes = write_tga_taskArgTypes;
nengel@3 205 write_tga_taskType->argSizes = write_tga_taskArgSizes;
nengel@3 206
nengel@3 207 write_tga_task_args args2;
nengel@0 208 char dummy;
nengel@3 209 for(i=0; i<ntasks;i++) {
nengel@3 210 args2.fp = fp;
nengel@3 211 args2.bufferlen = width*RGB_DEPTH*MCU_Y_STRIDE;
nengel@3 212 args2.rgb_data = rgb_data+i*RGB_DEPTH*width*MCU_Y_STRIDE;
nengel@3 213 args2.d = &dummy;
nengel@3 214 VSs__submit_task(write_tga_taskType, &args2, seedSlv);
nengel@0 215 }
nengel@0 216
nengel@3 217 VSs__taskwait(seedSlv);
nengel@0 218 //#pragma omp barrier
nengel@0 219
nengel@0 220 tinyjpeg_free(jdec);
nengel@0 221 for(i=0; i < ntasks; i++) {
nengel@0 222 tinyjpeg_free(jdec_task[i]);
nengel@0 223 }
nengel@0 224 fclose(fp);
nengel@2 225 VMS_App__free(buf);
nengel@2 226 VMS_App__free(rgb_data);
nengel@2 227 VMS_App__free(jdec_task);
nengel@0 228 return 0;
nengel@0 229 }
nengel@0 230
nengel@0 231 /*
nengel@0 232 * Usage information.
nengel@0 233 */
nengel@0 234 static void usage(void)
nengel@0 235 {
nengel@0 236 fprintf(stderr, "Usage: loadjpeg <input_filename.jpeg> <output_filename>\n");
nengel@0 237 exit(1);
nengel@0 238 }
nengel@0 239
nengel@0 240 /*
nengel@0 241 * Calculates the time difference between start and finish in msecs.
nengel@0 242 */
nengel@0 243 long timevaldiff(timer *start, timer *finish){
nengel@0 244 long msec;
nengel@0 245 msec = (finish->tv_sec - start->tv_sec)*1000;
nengel@0 246 msec += (finish->tv_usec - start->tv_usec)/1000;
nengel@0 247 return msec;
nengel@0 248 }
nengel@0 249
nengel@0 250
nengel@0 251 char *output_filename, *input_filename;
nengel@0 252 /**
nengel@0 253 * Benchmark MAIN
nengel@0 254 */
nengel@0 255 int main(int argc, char *argv[])
nengel@0 256 {
nengel@0 257
nengel@0 258 if (argc < 3)
nengel@0 259 usage();
nengel@0 260
nengel@0 261
nengel@0 262 input_filename = argv[1];
nengel@0 263 output_filename = argv[2];
nengel@0 264
nengel@0 265 VSs__create_seed_slave_and_do_work( &convert_one_image_wrapper,
nengel@0 266 NULL );
nengel@0 267
nengel@0 268
nengel@0 269
nengel@4 270 exit(0);
nengel@0 271 }
nengel@0 272
nengel@0 273
nengel@0 274
nengel@0 275 void convert_one_image_wrapper( void *_params, SlaveVP *animSlv ){
seanhalle@1 276 seedSlv = animSlv;
nengel@0 277
nengel@0 278 printf("Input file: %s\nOutput file: %s\n",input_filename,output_filename);
nengel@0 279
nengel@0 280 convert_one_image(input_filename, output_filename);
seanhalle@1 281
nengel@4 282 VSs__end_thread( animSlv );
nengel@0 283 }
nengel@0 284