_Motion Blur Effects_
by Tim Wittenberg

Listing One
#define MAXIMAGES
int motionBlur(char *firstImagePath, char *outputDir, int
 numFrames, int blurDepth){
  memImage *images[MAXIMAGES];
  char directory[MAXPATH],fileName[MAXPATH],prefix[MAXPATH],
    inSuffix[MAXPATH];
  char currentPath[MAXPATH], inPath[MAXPATH];
  int frameNum, i, j, status;
 if(blurDepth > MAXIMAGES){
    statusPrint("motionBlur: blurDepth is larger than the limit.");
    return -1;
  }
  // the directory includes the drive letter
  status = getPathPieces(firstImagePath, directory, fileName, prefix, &frameNum, inSuffix);
  if(status != 0){
    statusPrint("motionBlur: Check the first image pathname");
    return -2;
  }
  int imHeight, imWidth, bpp, frameCounter, row, col;
  status = readBMPHeader(firstImagePath, &imHeight, &imWidth, &bpp);
  if(status != 0){
    sprintf(g_msgText, "motionBlur: Cannot open: %s", firstImagePath);
    statusPrint(g_msgText);
    return -3;
  }
  for (frameCounter=frameNum;frameCounter<=frameNum+numFrames;frameCounter++){
    //  Open and close the appropriate images
    if(frameCounter == frameNum){
      for(i = 0; i < blurDepth; i++){ 
        makePath(currentPath, directory, prefix, 
          frameCounter + i, inSuffix);
        images[i] = 
          new memImage(currentPath, 0, 0, RANDOM, 
            'R', RGBCOLOR);
        if(!images[i]->isValid()){
            sprintf(g_msgText, 
             "motionBlur: unable to open image: %s",
              currentPath);
            statusPrint(g_msgText);
            return -4;
        }
      }
    }
    else{
        delete images[0];               //close oldest image
        for (j = 0; j < numFrames; j++)
            images[j] = images[j+1];
                                        //open new image
        makePath(currentPath, directory, prefix, 
          frameCounter + blurDepth-1, inSuffix);
        images[blurDepth-1] = new memImage(currentPath, 0, 0,RANDOM, 'R', RGBCOLOR);
}
//  blur the images
    char outPath[MAXPATH], outSuffix[MAXPATH];
    memImage *outImage;
    int blur;
    sprintf(outSuffix, "%s\0","b");
    makePath(outPath, outputDir, prefix, frameCounter,
     outSuffix);
    outImage = new memImage(imHeight, imWidth, bpp);
    BYTE red, green, blue;
    for (row = 1; row < imHeight; row++){
     for (col = 1; col < imWidth; col++){
        int bucket = 0;
        int redBucket = 0;
        int greenBucket = 0;
        int blueBucket = 0;
        for (blur = 0; blur < blurDepth; blur++){
          switch (bpp){
            case 8:
            bucket += images[blur]->getMPixel(col, row);
            break;
            case 24:
            images[blur]->getMPixelRGB(col, row, &red, &green,
             &blue);
            redBucket += red;
            greenBucket += green;
            blueBucket += blue;
            break;
            default:
            break;
          }  //end switch
          if(bpp == 8){
            float avgBucket = bucket/blurDepth;
            outImage->setMPixel(col, row, (BYTE)(avgBucket + 0.5));
          }
          if(bpp = 24){
            float avgRedBucket = redBucket/blurDepth;
            float avgGreenBucket = greenBucket/blurDepth;
            float avgBlueBucket = blueBucket/blurDepth;
            outImage->setMPixelRGB(col, row, 
            (BYTE)(avgRedBucket + 0.5),
            (BYTE)(avgGreenBucket + 0.5),
            (BYTE)(avgBlueBucket + 0.5));
          }
        }    //end inner loop
      }      //end outer loop
    }        //end frame loop
//  Save the blurred image
    sprintf(g_msgText,"Saving: %s", outPath);
    statusPrint(g_msgText);
    outImage->writeBMP(outPath);
    delete outImage;
}   //end sequence loop;
//  Close the remaining images
for(i = 0; i < blurDepth; i++)
  delete images[i];
return NULL;
}


