Advertisement
Guest User

Untitled

a guest
Dec 15th, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.21 KB | None | 0 0
  1. #include <pthread.h>
  2. #include <stdint.h>
  3. #include <ctype.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <sys/time.h>
  8. #include "ImageStuff.h"
  9.  
  10. struct ImgProp ip;
  11. #define IPHB ip.Hbytes
  12. #define IPH ip.Hpixels
  13. #define IPV ip.Vpixels
  14. #define IMAGESIZE (IPHB*IPV)
  15. #define IMAGEPIX (IPH*IPV)
  16. #define MAXTHREADS 128
  17. #define REPS 1
  18. #define BUFFER_SIZE 48*1024
  19.  
  20. long NumThreads; // Total number of threads working in parallel
  21. int ThParam[MAXTHREADS]; // Thread parameters ...
  22. pthread_t ThHandle[MAXTHREADS]; // Thread handles
  23. pthread_attr_t ThAttr; // Pthread attrributes
  24. void* (*ChangeSizeMT)(void *arg); // Function pointer to flip the image, multi-threaded version
  25. int XSVAR, YSVAR; // Global scaling factors
  26. int NewIPV, // Scaled down Verticle Pixels
  27. NewIPH, // Scaled down Horizontal Pixels
  28. NewIPHB; // Scaled down Horizontal Bytes
  29. long ChunkSize;
  30.  
  31. unsigned char** ImageInput; // This is the main image
  32. unsigned char** ImageOutput; // This is the post-processed image
  33.  
  34. // Function that reduces image size
  35. // based on user provided scale.
  36. void* Shrinker(void* tid)
  37. {
  38. int row, col;
  39. int RowSetter=0;
  40.  
  41. long ts = *((int*) tid);
  42. ts *= NewIPHB/NumThreads;
  43. long te = ts + NewIPHB/NumThreads -1;
  44.  
  45. for(row=0; row<NewIPV-1; row++){
  46. for(col=ts; col<=te; col+= 3){
  47. ImageOutput[row][col] = ImageInput[RowSetter][col * XSVAR];
  48. ImageOutput[row][col+1] = ImageInput[RowSetter][col * XSVAR +1];
  49. ImageOutput[row][col+2] = ImageInput[RowSetter][col * XSVAR +2];
  50. }
  51. RowSetter+=YSVAR;
  52. }
  53. }
  54.  
  55. int main(int argc, char** argv)
  56. {
  57. int a,i,ThErr, xShrink, yShrink;
  58. struct timeval t;
  59. double StartTime, EndTime;
  60. double TimeElapsed;
  61.  
  62. switch (argc){
  63. case 5 : NumThreads=0; xShrink = atoi(argv[3]); yShrink = atoi(argv[4]); ChangeSizeMT = Shrinker; break;
  64. case 6 : NumThreads=atoi(argv[5]); xShrink = atoi(argv[3]); yShrink = atoi(argv[4]); ChangeSizeMT = Shrinker; break;
  65. default: printf("\n\nUsage: ./imshrunk input output xshrink yshrink NumberOfThreads");
  66. printf("\n\nNumThreads=0 OR leave blank for the serial version, and 1-128 for the Pthreads version\n");
  67. printf("\nExample: imshrunk inputImage.bmp outputImage.bmp 100 5 4\n");
  68. printf("\nExample: imshrunk inputImage.bmp outputImage.bmp 100 5\n");
  69. printf("\nNothing executed ... Exiting ...\n\n");
  70. exit(EXIT_FAILURE);
  71. }
  72. if((xShrink == 0) && (yShrink == 0)){
  73. printf("\nEither scaling factor (X or Y) must be greater than 1");
  74. printf("\nNo execution required, Exiting Program...\n\n");
  75. exit(EXIT_FAILURE);
  76. }
  77. if((xShrink < 0) || (yShrink < 0)){
  78. printf("\nCannot downscale the image by a negative integer");
  79. printf("\nEnter a non-negative integer to Shrinker the image. Exiting Program...\n\n");
  80. exit(EXIT_FAILURE);
  81. }
  82. if((NumThreads<0) || (NumThreads>MAXTHREADS)){
  83. printf("\nNumber of threads must be between 0 and %u... \n",MAXTHREADS);
  84. printf("\n'1' means Pthreads version with a single thread\n");
  85. printf("\nYou can also specify '0' which means the 'serial' (non-Pthreads) version... \n\n");
  86. printf("\n\nNothing executed ... Exiting ...\n\n");
  87. exit(EXIT_FAILURE);
  88. }
  89. if(NumThreads == 0){
  90. printf("\nExecuting the serial (non-Pthreaded) version ...\n");
  91. ChunkSize = NewIPHB;
  92. }else{
  93. printf("\nExecuting the multi-threaded version with %li threads ...\n",NumThreads);
  94. ChunkSize = NewIPHB/NumThreads;
  95. }
  96.  
  97. ImageInput = ReadBMP(argv[1]);
  98. ImageOutput = CreateBlankBMP(225);
  99.  
  100. XSVAR = xShrink;
  101. YSVAR = yShrink;
  102. NewIPH = IPH/xShrink;
  103. NewIPV = IPV/yShrink;
  104. NewIPHB = (NewIPH*3 + 3) & (~3);
  105.  
  106. //printf("\nNewIPV: %i\t NewIPH: %i\t NewIPHB: %i\nChunkSize: %li\n", NewIPV, NewIPH, NewIPHB, ChunkSize);
  107. gettimeofday(&t, NULL);
  108. StartTime = (double)t.tv_sec*1000000.0 + ((double)t.tv_usec);
  109.  
  110. if(NumThreads >0){
  111. pthread_attr_init(&ThAttr);
  112. pthread_attr_setdetachstate(&ThAttr, PTHREAD_CREATE_JOINABLE);
  113. for(a=0; a<REPS; a++){
  114. for(i=0; i<NumThreads; i++){
  115. ThParam[i] = i;
  116. ThErr = pthread_create(&ThHandle[i], &ThAttr, ChangeSizeMT, (void *)&ThParam[i]);
  117. if(ThErr != 0){
  118. printf("\nThread Creation Error %d. Exiting abruptly... \n",ThErr);
  119. exit(EXIT_FAILURE);
  120. }
  121. }
  122. for(i=0; i<NumThreads; i++){
  123. pthread_join(ThHandle[i], NULL);
  124. }
  125. }
  126. }else{
  127. printf("\n!!!Execution Failure!!!\n");
  128. }
  129.  
  130. gettimeofday(&t, NULL);
  131. EndTime = (double)t.tv_sec*1000000.0 + ((double)t.tv_usec);
  132. TimeElapsed=(EndTime-StartTime)/1000.00;
  133. TimeElapsed/=(double)REPS;
  134.  
  135. //merge with header and write to file
  136. WriteBMP(ImageOutput, argv[2], NewIPH, NewIPV);
  137.  
  138. // free() the allocated memory for the image
  139. for(i = 0; i < ip.Vpixels; i++) { free(ImageInput[i]); }
  140. for(i = 0; i < ip.Vpixels; i++) { free(ImageOutput[i]); }
  141. free(ImageInput);
  142. free(ImageOutput);
  143.  
  144. printf("\n\nTotal execution time: %9.4f ms. ",TimeElapsed);
  145. if(NumThreads>1) printf("(%9.4f ms per thread). ",TimeElapsed/(double)NumThreads);
  146. printf("\n (%6.3f ns/pixel)\n", 1000000*TimeElapsed/(double)(ip.Hpixels*ip.Vpixels));
  147.  
  148. return (EXIT_SUCCESS);
  149. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement