Commits

Anonymous committed a911a64

Simple program inverting color in BMP files

  • Participants

Comments (0)

Files changed (1)

File bmp-color-inverter.cu

+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+
+void checkCUDAError(const char *msg);
+
+__global__ void kernel(uint8_t *data, long size)
+{
+  int idx = blockIdx.x * blockDim.x + threadIdx.x;
+  if(idx < size)
+    data[idx] = 255 - data[idx];
+}
+
+int main(int argc, char *argv[])
+{
+  FILE *fp;
+  size_t offset, x;
+  long size;
+  uint8_t *data, *device_mem_ptr;
+
+  /* Cecking input parameters */
+  if(argc < 2)
+  {
+    printf("Too few arguments\nUsage: %s <image.bmp>\n", argv[0]);
+    exit(1);
+  }
+
+  /* Open file in binary read mode */
+  fp = fopen(argv[1], "r+b");
+
+  /* Read offset of image data */
+  fseek(fp, 10, SEEK_SET);
+  x = fread(&offset, 1, 4, fp);
+
+  /* Check the length od image data */
+  fseek(fp, 0, SEEK_END);
+  size = ftell(fp);
+  size = size - offset;
+
+  /* Copy image data to memory */
+  fseek(fp, offset, SEEK_SET);
+  data = (uint8_t*)malloc(size);
+  x = fread(data, 1, size, fp);
+
+//--------------------
+
+  /* Allocating memory on the device */
+  cudaMalloc((void**)&device_mem_ptr, size);
+
+  /* Copying data to the device */
+  cudaMemcpy(device_mem_ptr, data, size, cudaMemcpyHostToDevice);
+
+  /* Calling the kernel */
+  int threads = 256;
+  int blocks = (size/threads)+1;
+  printf("%d %d %d\n", threads, blocks, threads*blocks);
+  kernel<<<blocks, threads>>>(device_mem_ptr, size);
+
+  /* Copying data back */
+  cudaMemcpy(data, device_mem_ptr, size, cudaMemcpyDeviceToHost);
+
+  /* Check if any error occured */
+  checkCUDAError("Error: ");
+
+  /* Free memory on the device */
+  cudaFree(device_mem_ptr);
+
+//--------------------
+
+  /* Save changes to file */
+  fseek(fp, offset, SEEK_SET);
+  x = fwrite(data, 1, size, fp);
+
+  /* Close file */
+  fclose(fp);
+
+  /* Free memory */
+  free(data);
+
+  return 0;
+}
+
+void checkCUDAError(const char *msg)
+{
+  cudaError_t err = cudaGetLastError();
+  if( cudaSuccess != err)
+  {
+    fprintf(stderr, "Cuda error: %s: %s\n", msg, cudaGetErrorString( err) );
+    exit(2);
+  }
+}