annotate VSs_tinyjpeg/loadjpeg.c @ 0:a8af8b3fc99d

initial commit
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Thu, 05 Jul 2012 11:35:03 +0200
parents
children 7e13c9ecc89c
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@0 91 //todo
nengel@0 92 //#pragma omp task input(*rgb_data) output(*d) inout(*d)
nengel@0 93 void write_tga_task(FILE* fp, int bufferlen, unsigned char* rgb_data, char* d) {
nengel@0 94
nengel@0 95 // To disable ompss warnings
nengel@0 96 d = d;
nengel@0 97 unsigned char *data = rgb_data + bufferlen - RGB_DEPTH;
nengel@0 98 do
nengel@0 99 {
nengel@0 100 unsigned char c = data[0];
nengel@0 101 data[0] = data[2];
nengel@0 102 data[2] = c;
nengel@0 103 data-=RGB_DEPTH;
nengel@0 104 } while (data >= rgb_data);
nengel@0 105
nengel@0 106 fwrite(rgb_data, 1, bufferlen, fp);
nengel@0 107 }
nengel@0 108
nengel@0 109
nengel@0 110 int32 tinyjpegArgTypes[2] = {IN, OUT};
nengel@0 111 int32 tinyjpegArgSizes[2] = {sizeof(struct jdec_private), sizeof(uint8_t)};
nengel@0 112
nengel@0 113 /**
nengel@0 114 * Load one jpeg image, and decompress it, and save the result.
nengel@0 115 */
nengel@0 116 int convert_one_image(const char *infilename, const char *outfilename)
nengel@0 117 {
nengel@0 118 FILE *fp;
nengel@0 119 unsigned int length_of_file;
nengel@0 120 unsigned int width, height;
nengel@0 121 unsigned char *buf;
nengel@0 122 struct jdec_private *jdec; //for parsing header
nengel@0 123 struct jdec_private **jdec_task; //for decoding mcus
nengel@0 124 uint8_t *rgb_data;
nengel@0 125 int i;
nengel@0 126 int ntasks;
nengel@0 127
nengel@0 128 /* Load the Jpeg into memory */
nengel@0 129 fp = fopen(infilename, "rb");
nengel@0 130 if (fp == NULL)
nengel@0 131 perror("Cannot open image");//exitmessage("Cannot open filename\n");
nengel@0 132 length_of_file = filesize(fp);
nengel@0 133 buf = (unsigned char *)malloc(length_of_file + 4);
nengel@0 134 if (buf == NULL)
nengel@0 135 exitmessage("Not enough memory for loading file\n");
nengel@0 136 fread(buf, length_of_file, 1, fp);
nengel@0 137 fclose(fp);
nengel@0 138
nengel@0 139 /* Decompress it */
nengel@0 140 jdec = tinyjpeg_init();
nengel@0 141 if (jdec == NULL)
nengel@0 142 exitmessage("Not enough memory to alloc the structure need for decompressing\n");
nengel@0 143
nengel@0 144 if (tinyjpeg_parse_header(jdec, buf, length_of_file)<0)
nengel@0 145 exitmessage(tinyjpeg_get_errorstring());
nengel@0 146
nengel@0 147 /* Get the size of the image */
nengel@0 148 tinyjpeg_get_size(jdec, &width, &height);
nengel@0 149
nengel@0 150 // RGB stuff
nengel@0 151 rgb_data = (uint8_t *)malloc(width * height * RGB_DEPTH);
nengel@0 152 jdec->components[0] = rgb_data;
nengel@0 153
nengel@0 154 // this jpeg decoder only supports full MCUs for simplicity
nengel@0 155 ntasks = (jdec->mcus_in_width * jdec->mcus_in_height)/ jdec->restart_interval;
nengel@0 156 jdec_task = (struct jdec_private **) malloc ( ntasks * sizeof(struct jdec_private*));
nengel@0 157
nengel@0 158
nengel@0 159 //VSs setup
nengel@0 160 tinyjpegTaskType = VMS_App__malloc( sizeof(VSsTaskType) );
nengel@0 161 tinyjpegTaskType->fn = &tinyjpeg_decode_task;
nengel@0 162 tinyjpegTaskType->numCtldArgs = 2;
nengel@0 163 tinyjpegTaskType->numTotalArgs = 2;
nengel@0 164 tinyjpegTaskType->sizeOfArgs = sizeof(tinyjpeg_decode_task_args);
nengel@0 165 tinyjpegTaskType->argTypes = tinyjpegArgTypes;
nengel@0 166 tinyjpegTaskType->argSizes = tinyjpegArgSizes;
nengel@0 167
nengel@0 168 tinyjpeg_decode_task_args args;
nengel@0 169
nengel@0 170 fp = write_tga_header(outfilename, width, height);
nengel@0 171 printf("Decoding JPEG image...\n");
nengel@0 172 for (i=0; i<ntasks; i++){
nengel@0 173 jdec_task[i] = create_jdec_priv_task(jdec, i);
nengel@0 174
nengel@0 175 args.priv = jdec_task[i];
nengel@0 176 args.context = rgb_data+i*width*RGB_DEPTH*MCU_Y_STRIDE;
nengel@0 177 VSs__submit_task(tinyjpegTaskType, &args, master);
nengel@0 178
nengel@0 179 }
nengel@0 180
nengel@0 181 char dummy;
nengel@0 182 for(i=0; i<ntasks;i++) {
nengel@0 183 write_tga_task(fp, width*RGB_DEPTH*MCU_Y_STRIDE, rgb_data+i*RGB_DEPTH*width*MCU_Y_STRIDE, &dummy);
nengel@0 184 }
nengel@0 185
nengel@0 186 //VSs__wait_for_all_tasks_to_complete();
nengel@0 187 //#pragma omp barrier
nengel@0 188
nengel@0 189 tinyjpeg_free(jdec);
nengel@0 190 for(i=0; i < ntasks; i++) {
nengel@0 191 tinyjpeg_free(jdec_task[i]);
nengel@0 192 }
nengel@0 193 fclose(fp);
nengel@0 194 free(buf);
nengel@0 195 free(rgb_data);
nengel@0 196 free(jdec_task);
nengel@0 197 return 0;
nengel@0 198 }
nengel@0 199
nengel@0 200 /*
nengel@0 201 * Usage information.
nengel@0 202 */
nengel@0 203 static void usage(void)
nengel@0 204 {
nengel@0 205 fprintf(stderr, "Usage: loadjpeg <input_filename.jpeg> <output_filename>\n");
nengel@0 206 exit(1);
nengel@0 207 }
nengel@0 208
nengel@0 209 /*
nengel@0 210 * Calculates the time difference between start and finish in msecs.
nengel@0 211 */
nengel@0 212 long timevaldiff(timer *start, timer *finish){
nengel@0 213 long msec;
nengel@0 214 msec = (finish->tv_sec - start->tv_sec)*1000;
nengel@0 215 msec += (finish->tv_usec - start->tv_usec)/1000;
nengel@0 216 return msec;
nengel@0 217 }
nengel@0 218
nengel@0 219
nengel@0 220 char *output_filename, *input_filename;
nengel@0 221 /**
nengel@0 222 * Benchmark MAIN
nengel@0 223 */
nengel@0 224 int main(int argc, char *argv[])
nengel@0 225 {
nengel@0 226
nengel@0 227 if (argc < 3)
nengel@0 228 usage();
nengel@0 229
nengel@0 230
nengel@0 231 input_filename = argv[1];
nengel@0 232 output_filename = argv[2];
nengel@0 233
nengel@0 234 VSs__create_seed_slave_and_do_work( &convert_one_image_wrapper,
nengel@0 235 NULL );
nengel@0 236
nengel@0 237
nengel@0 238
nengel@0 239 return 0;
nengel@0 240 }
nengel@0 241
nengel@0 242
nengel@0 243
nengel@0 244 void convert_one_image_wrapper( void *_params, SlaveVP *animSlv ){
nengel@0 245 master = animSlv;
nengel@0 246
nengel@0 247 printf("Input file: %s\nOutput file: %s\n",input_filename,output_filename);
nengel@0 248
nengel@0 249 convert_one_image(input_filename, output_filename);
nengel@0 250 }
nengel@0 251