annotate VSs_tinyjpeg/loadjpeg.c @ 3:42d636fee562

added second type of task
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Fri, 13 Jul 2012 17:59:00 +0200
parents a52de05d2e2b
children 62350c40504f
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@3 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@3 106 write_tga_task_args* args = (write_tga_task_args*) _data;
nengel@3 107 FILE* fp = args->fp;
nengel@3 108 int bufferlen = args->bufferlen;
nengel@3 109 unsigned char* rgb_data = args->rgb_data;
nengel@3 110 char* d = args->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@0 124 }
nengel@0 125
nengel@0 126
nengel@0 127 int32 tinyjpegArgTypes[2] = {IN, OUT};
nengel@0 128 int32 tinyjpegArgSizes[2] = {sizeof(struct jdec_private), sizeof(uint8_t)};
nengel@0 129
nengel@0 130 /**
nengel@0 131 * Load one jpeg image, and decompress it, and save the result.
nengel@0 132 */
nengel@0 133 int convert_one_image(const char *infilename, const char *outfilename)
nengel@0 134 {
nengel@0 135 FILE *fp;
nengel@0 136 unsigned int length_of_file;
nengel@0 137 unsigned int width, height;
nengel@0 138 unsigned char *buf;
nengel@0 139 struct jdec_private *jdec; //for parsing header
nengel@0 140 struct jdec_private **jdec_task; //for decoding mcus
nengel@0 141 uint8_t *rgb_data;
nengel@0 142 int i;
nengel@0 143 int ntasks;
nengel@0 144
nengel@0 145 /* Load the Jpeg into memory */
nengel@0 146 fp = fopen(infilename, "rb");
nengel@0 147 if (fp == NULL)
nengel@0 148 perror("Cannot open image");//exitmessage("Cannot open filename\n");
nengel@0 149 length_of_file = filesize(fp);
nengel@2 150 buf = (unsigned char *)VMS_App__malloc(length_of_file + 4);
nengel@0 151 if (buf == NULL)
nengel@0 152 exitmessage("Not enough memory for loading file\n");
nengel@0 153 fread(buf, length_of_file, 1, fp);
nengel@0 154 fclose(fp);
nengel@0 155
nengel@0 156 /* Decompress it */
nengel@0 157 jdec = tinyjpeg_init();
nengel@0 158 if (jdec == NULL)
nengel@0 159 exitmessage("Not enough memory to alloc the structure need for decompressing\n");
nengel@0 160
nengel@0 161 if (tinyjpeg_parse_header(jdec, buf, length_of_file)<0)
nengel@0 162 exitmessage(tinyjpeg_get_errorstring());
nengel@0 163
nengel@0 164 /* Get the size of the image */
nengel@0 165 tinyjpeg_get_size(jdec, &width, &height);
nengel@0 166
nengel@0 167 // RGB stuff
nengel@2 168 rgb_data = (uint8_t *)VMS_App__malloc(width * height * RGB_DEPTH);
nengel@0 169 jdec->components[0] = rgb_data;
nengel@0 170
nengel@0 171 // this jpeg decoder only supports full MCUs for simplicity
nengel@0 172 ntasks = (jdec->mcus_in_width * jdec->mcus_in_height)/ jdec->restart_interval;
nengel@2 173 jdec_task = (struct jdec_private **) VMS_App__malloc ( ntasks * sizeof(struct jdec_private*));
nengel@0 174
nengel@0 175
nengel@0 176 //VSs setup
nengel@0 177 tinyjpegTaskType = VMS_App__malloc( sizeof(VSsTaskType) );
nengel@0 178 tinyjpegTaskType->fn = &tinyjpeg_decode_task;
nengel@0 179 tinyjpegTaskType->numCtldArgs = 2;
nengel@0 180 tinyjpegTaskType->numTotalArgs = 2;
nengel@0 181 tinyjpegTaskType->sizeOfArgs = sizeof(tinyjpeg_decode_task_args);
nengel@0 182 tinyjpegTaskType->argTypes = tinyjpegArgTypes;
nengel@0 183 tinyjpegTaskType->argSizes = tinyjpegArgSizes;
nengel@0 184
nengel@0 185 tinyjpeg_decode_task_args args;
nengel@0 186
nengel@0 187 fp = write_tga_header(outfilename, width, height);
nengel@0 188 printf("Decoding JPEG image...\n");
nengel@0 189 for (i=0; i<ntasks; i++){
nengel@0 190 jdec_task[i] = create_jdec_priv_task(jdec, i);
nengel@0 191
nengel@0 192 args.priv = jdec_task[i];
nengel@0 193 args.context = rgb_data+i*width*RGB_DEPTH*MCU_Y_STRIDE;
seanhalle@1 194 VSs__submit_task(tinyjpegTaskType, &args, seedSlv);
nengel@0 195
nengel@0 196 }
nengel@0 197
nengel@3 198 write_tga_taskType = VMS_App__malloc( sizeof(VSsTaskType) );
nengel@3 199 write_tga_taskType->fn = &write_tga_task;
nengel@3 200 write_tga_taskType->numCtldArgs = 2;
nengel@3 201 write_tga_taskType->numTotalArgs = 4;
nengel@3 202 write_tga_taskType->sizeOfArgs = sizeof(write_tga_task_args);
nengel@3 203 write_tga_taskType->argTypes = write_tga_taskArgTypes;
nengel@3 204 write_tga_taskType->argSizes = write_tga_taskArgSizes;
nengel@3 205
nengel@3 206 write_tga_task_args args2;
nengel@0 207 char dummy;
nengel@3 208 for(i=0; i<ntasks;i++) {
nengel@3 209 args2.fp = fp;
nengel@3 210 args2.bufferlen = width*RGB_DEPTH*MCU_Y_STRIDE;
nengel@3 211 args2.rgb_data = rgb_data+i*RGB_DEPTH*width*MCU_Y_STRIDE;
nengel@3 212 args2.d = &dummy;
nengel@3 213 VSs__submit_task(write_tga_taskType, &args2, seedSlv);
nengel@0 214 }
nengel@0 215
nengel@3 216 VSs__taskwait(seedSlv);
nengel@0 217 //#pragma omp barrier
nengel@0 218
nengel@0 219 tinyjpeg_free(jdec);
nengel@0 220 for(i=0; i < ntasks; i++) {
nengel@0 221 tinyjpeg_free(jdec_task[i]);
nengel@0 222 }
nengel@0 223 fclose(fp);
nengel@2 224 VMS_App__free(buf);
nengel@2 225 VMS_App__free(rgb_data);
nengel@2 226 VMS_App__free(jdec_task);
nengel@0 227 return 0;
nengel@0 228 }
nengel@0 229
nengel@0 230 /*
nengel@0 231 * Usage information.
nengel@0 232 */
nengel@0 233 static void usage(void)
nengel@0 234 {
nengel@0 235 fprintf(stderr, "Usage: loadjpeg <input_filename.jpeg> <output_filename>\n");
nengel@0 236 exit(1);
nengel@0 237 }
nengel@0 238
nengel@0 239 /*
nengel@0 240 * Calculates the time difference between start and finish in msecs.
nengel@0 241 */
nengel@0 242 long timevaldiff(timer *start, timer *finish){
nengel@0 243 long msec;
nengel@0 244 msec = (finish->tv_sec - start->tv_sec)*1000;
nengel@0 245 msec += (finish->tv_usec - start->tv_usec)/1000;
nengel@0 246 return msec;
nengel@0 247 }
nengel@0 248
nengel@0 249
nengel@0 250 char *output_filename, *input_filename;
nengel@0 251 /**
nengel@0 252 * Benchmark MAIN
nengel@0 253 */
nengel@0 254 int main(int argc, char *argv[])
nengel@0 255 {
nengel@0 256
nengel@0 257 if (argc < 3)
nengel@0 258 usage();
nengel@0 259
nengel@0 260
nengel@0 261 input_filename = argv[1];
nengel@0 262 output_filename = argv[2];
nengel@0 263
nengel@0 264 VSs__create_seed_slave_and_do_work( &convert_one_image_wrapper,
nengel@0 265 NULL );
nengel@0 266
nengel@0 267
nengel@0 268
nengel@0 269 return 0;
nengel@0 270 }
nengel@0 271
nengel@0 272
nengel@0 273
nengel@0 274 void convert_one_image_wrapper( void *_params, SlaveVP *animSlv ){
seanhalle@1 275 seedSlv = animSlv;
nengel@0 276
nengel@0 277 printf("Input file: %s\nOutput file: %s\n",input_filename,output_filename);
nengel@0 278
nengel@0 279 convert_one_image(input_filename, output_filename);
seanhalle@1 280
seanhalle@1 281 VSs__dissipate_slave( animSlv );
nengel@0 282 }
nengel@0 283