Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <pthread.h>
- #include <stdint.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/time.h>
- #include "ImageStuff.h"
- struct ImgProp ip;
- #define IPHB ip.Hbytes
- #define IPH ip.Hpixels
- #define IPV ip.Vpixels
- #define IMAGESIZE (IPHB*IPV)
- #define IMAGEPIX (IPH*IPV)
- #define MAXTHREADS 128
- #define REPS 1
- #define BUFFER_SIZE 48*1024
- long NumThreads; // Total number of threads working in parallel
- int ThParam[MAXTHREADS]; // Thread parameters ...
- pthread_t ThHandle[MAXTHREADS]; // Thread handles
- pthread_attr_t ThAttr; // Pthread attrributes
- void* (*ChangeSizeMT)(void *arg); // Function pointer to flip the image, multi-threaded version
- int XSVAR, YSVAR; // Global scaling factors
- int NewIPV, // Scaled down Verticle Pixels
- NewIPH, // Scaled down Horizontal Pixels
- NewIPHB; // Scaled down Horizontal Bytes
- long ChunkSize;
- unsigned char** ImageInput; // This is the main image
- unsigned char** ImageOutput; // This is the post-processed image
- // Function that reduces image size
- // based on user provided scale.
- void* Shrinker(void* tid)
- {
- int row, col;
- int RowSetter=0;
- long ts = *((int*) tid);
- ts *= NewIPHB/NumThreads;
- long te = ts + NewIPHB/NumThreads -1;
- for(row=0; row<NewIPV-1; row++){
- for(col=ts; col<=te; col+= 3){
- ImageOutput[row][col] = ImageInput[RowSetter][col * XSVAR];
- ImageOutput[row][col+1] = ImageInput[RowSetter][col * XSVAR +1];
- ImageOutput[row][col+2] = ImageInput[RowSetter][col * XSVAR +2];
- }
- RowSetter+=YSVAR;
- }
- }
- int main(int argc, char** argv)
- {
- int a,i,ThErr, xShrink, yShrink;
- struct timeval t;
- double StartTime, EndTime;
- double TimeElapsed;
- switch (argc){
- case 5 : NumThreads=0; xShrink = atoi(argv[3]); yShrink = atoi(argv[4]); ChangeSizeMT = Shrinker; break;
- case 6 : NumThreads=atoi(argv[5]); xShrink = atoi(argv[3]); yShrink = atoi(argv[4]); ChangeSizeMT = Shrinker; break;
- default: printf("\n\nUsage: ./imshrunk input output xshrink yshrink NumberOfThreads");
- printf("\n\nNumThreads=0 OR leave blank for the serial version, and 1-128 for the Pthreads version\n");
- printf("\nExample: imshrunk inputImage.bmp outputImage.bmp 100 5 4\n");
- printf("\nExample: imshrunk inputImage.bmp outputImage.bmp 100 5\n");
- printf("\nNothing executed ... Exiting ...\n\n");
- exit(EXIT_FAILURE);
- }
- if((xShrink == 0) && (yShrink == 0)){
- printf("\nEither scaling factor (X or Y) must be greater than 1");
- printf("\nNo execution required, Exiting Program...\n\n");
- exit(EXIT_FAILURE);
- }
- if((xShrink < 0) || (yShrink < 0)){
- printf("\nCannot downscale the image by a negative integer");
- printf("\nEnter a non-negative integer to Shrinker the image. Exiting Program...\n\n");
- exit(EXIT_FAILURE);
- }
- if((NumThreads<0) || (NumThreads>MAXTHREADS)){
- printf("\nNumber of threads must be between 0 and %u... \n",MAXTHREADS);
- printf("\n'1' means Pthreads version with a single thread\n");
- printf("\nYou can also specify '0' which means the 'serial' (non-Pthreads) version... \n\n");
- printf("\n\nNothing executed ... Exiting ...\n\n");
- exit(EXIT_FAILURE);
- }
- if(NumThreads == 0){
- printf("\nExecuting the serial (non-Pthreaded) version ...\n");
- ChunkSize = NewIPHB;
- }else{
- printf("\nExecuting the multi-threaded version with %li threads ...\n",NumThreads);
- ChunkSize = NewIPHB/NumThreads;
- }
- ImageInput = ReadBMP(argv[1]);
- ImageOutput = CreateBlankBMP(225);
- XSVAR = xShrink;
- YSVAR = yShrink;
- NewIPH = IPH/xShrink;
- NewIPV = IPV/yShrink;
- NewIPHB = (NewIPH*3 + 3) & (~3);
- //printf("\nNewIPV: %i\t NewIPH: %i\t NewIPHB: %i\nChunkSize: %li\n", NewIPV, NewIPH, NewIPHB, ChunkSize);
- gettimeofday(&t, NULL);
- StartTime = (double)t.tv_sec*1000000.0 + ((double)t.tv_usec);
- if(NumThreads >0){
- pthread_attr_init(&ThAttr);
- pthread_attr_setdetachstate(&ThAttr, PTHREAD_CREATE_JOINABLE);
- for(a=0; a<REPS; a++){
- for(i=0; i<NumThreads; i++){
- ThParam[i] = i;
- ThErr = pthread_create(&ThHandle[i], &ThAttr, ChangeSizeMT, (void *)&ThParam[i]);
- if(ThErr != 0){
- printf("\nThread Creation Error %d. Exiting abruptly... \n",ThErr);
- exit(EXIT_FAILURE);
- }
- }
- for(i=0; i<NumThreads; i++){
- pthread_join(ThHandle[i], NULL);
- }
- }
- }else{
- printf("\n!!!Execution Failure!!!\n");
- }
- gettimeofday(&t, NULL);
- EndTime = (double)t.tv_sec*1000000.0 + ((double)t.tv_usec);
- TimeElapsed=(EndTime-StartTime)/1000.00;
- TimeElapsed/=(double)REPS;
- //merge with header and write to file
- WriteBMP(ImageOutput, argv[2], NewIPH, NewIPV);
- // free() the allocated memory for the image
- for(i = 0; i < ip.Vpixels; i++) { free(ImageInput[i]); }
- for(i = 0; i < ip.Vpixels; i++) { free(ImageOutput[i]); }
- free(ImageInput);
- free(ImageOutput);
- printf("\n\nTotal execution time: %9.4f ms. ",TimeElapsed);
- if(NumThreads>1) printf("(%9.4f ms per thread). ",TimeElapsed/(double)NumThreads);
- printf("\n (%6.3f ns/pixel)\n", 1000000*TimeElapsed/(double)(ip.Hpixels*ip.Vpixels));
- return (EXIT_SUCCESS);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement