Guest User

Untitled

a guest
Jan 5th, 2016
937
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.96 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5.  
  6. typedef struct {
  7.  
  8.      unsigned char red,green,blue;
  9. } PPMPixel;
  10.  
  11. typedef struct {
  12.  
  13.      int x, y;
  14.      PPMPixel *data;
  15. } PPMImage;
  16.  
  17. typedef unsigned char uint8_t;
  18. typedef signed char int8_t;
  19. typedef unsigned short uint16_t;
  20. typedef signed short int16_t;
  21.  
  22. #define CREATOR "FELIXKLEMM"
  23. #define RGB_COMPONENT_COLOR 255
  24.  
  25. #define INP_PATH "Bilder/image.ppm"
  26. #define OUT_PATH "Bilder/image_out.ppm"
  27.  
  28. #define W 21
  29. #define H 20
  30.  
  31. #define CLAMP(v, min, max) if(v < min) { v = min; } else if(v > max) { v = max; }
  32.  
  33. static PPMImage *readPPM(const char *filename) {
  34.  
  35.     char buff[16];
  36.     PPMImage *img;
  37.     FILE *fp;
  38.  
  39.     int c, rgb_comp_color;
  40.  
  41.     //open PPM file for reading
  42.     fp = fopen(filename, "rb");
  43.     if(!fp) {
  44.  
  45.         fprintf(stderr, "Unable to open file '%s'\n", filename);
  46.         exit(1);
  47.     }
  48.  
  49.     //read image format
  50.     if(!fgets(buff, sizeof(buff), fp)) {
  51.  
  52.         perror(filename);
  53.         exit(1);
  54.     }
  55.  
  56.     //check the image format
  57.     if(buff[0] != 'P' || buff[1] != '6') {
  58.  
  59.         fprintf(stderr, "Invalid image format (must be 'P6')\n");
  60.         exit(1);
  61.     }
  62.  
  63.     //alloc memory form image
  64.     img = (PPMImage *)malloc(sizeof(PPMImage));
  65.     if(!img) {
  66.  
  67.         fprintf(stderr, "Unable to allocate memory\n");
  68.         exit(1);
  69.     }
  70.  
  71.     //check for comments
  72.     c = getc(fp);
  73.     while (c == '#') {
  74.  
  75.         while (getc(fp) != '\n');
  76.         c = getc(fp);
  77.     }
  78.  
  79.     ungetc(c, fp);
  80.     //read image size information
  81.     if(fscanf(fp, "%d %d", &img->x, &img->y) != 2) {
  82.  
  83.         fprintf(stderr, "Invalid image size (error loading '%s')\n", filename);
  84.         exit(1);
  85.     }
  86.  
  87.     //read rgb component
  88.     if(fscanf(fp, "%d", &rgb_comp_color) != 1) {
  89.         fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename);
  90.         exit(1);
  91.     }
  92.  
  93.     //check rgb component depth
  94.     if(rgb_comp_color!= RGB_COMPONENT_COLOR) {
  95.         fprintf(stderr, "'%s' does not have 8-bits components\n", filename);
  96.         exit(1);
  97.     }
  98.  
  99.     while (fgetc(fp) != '\n');
  100.     //memory allocation for pixel data
  101.     img->data = (PPMPixel*)malloc(img->x * img->y * sizeof(PPMPixel));
  102.  
  103.     if(!img) {
  104.  
  105.         fprintf(stderr, "Unable to allocate memory\n");
  106.         exit(1);
  107.     }
  108.  
  109.     //read pixel data from file
  110.     if(fread(img->data, 3 * img->x, img->y, fp) != img->y) {
  111.  
  112.         fprintf(stderr, "Error loading image '%s'\n", filename);
  113.         exit(1);
  114.     }
  115.  
  116.     fclose(fp);
  117.     return img;
  118. }
  119.  
  120. static PPMImage *init_destination_image(float scale) {
  121.  
  122.     PPMImage *img;
  123.  
  124.     //alloc memory form image
  125.     img = (PPMImage *)malloc(sizeof(PPMImage));
  126.     if(!img) {
  127.  
  128.         fprintf(stderr, "Unable to allocate memory\n");
  129.         exit(1);
  130.     }
  131.  
  132.     //memory allocation for pixel data
  133.     img->data = (PPMPixel*)malloc(W * H * (int)scale * sizeof(PPMPixel));
  134.     if(!img) {
  135.  
  136.         fprintf(stderr, "Unable to allocate memory\n");
  137.         exit(1);
  138.     }
  139.     return img;
  140. }
  141.  
  142. void writePPM(const char *filename, PPMImage *img)
  143. {
  144.     FILE *fp;
  145.     //open file for output
  146.     fp = fopen(filename, "wb");
  147.     if (!fp) {
  148.          fprintf(stderr, "Unable to open file '%s'\n", filename);
  149.          exit(1);
  150.     }
  151.  
  152.     //write the header file
  153.     //image format
  154.     fprintf(fp, "P6\n");
  155.  
  156.     //comments
  157.     fprintf(fp, "# Created by %s\n",CREATOR);
  158.  
  159.     //image size
  160.     fprintf(fp, "%d %d\n",img->x,img->y);
  161.  
  162.     // rgb component depth
  163.     fprintf(fp, "%d\n",RGB_COMPONENT_COLOR);
  164.  
  165.     // pixel data
  166.     fwrite(img->data, 3 * img->x, img->y, fp);
  167.     fclose(fp);
  168. }
  169.  
  170. float cubic_hermite(float A, float B, float C, float D, float t) {
  171.  
  172.     float a = -A / 2.0f + (3.0f*B) / 2.0f - (3.0f*C) / 2.0f + D / 2.0f;
  173.     float b = A - (5.0f*B) / 2.0f + 2.0f*C - D / 2.0f;
  174.     float c = -A / 2.0f + C / 2.0f;
  175.     float d = B;
  176.  
  177.     return a*t*t*t + b*t*t + c*t + d;
  178. }
  179.  
  180. void get_pixel_clamped(PPMImage *source_image, int x, int y, uint8_t temp[])  {
  181.  
  182.     CLAMP(x, 0, source_image->x - 1);
  183.     CLAMP(y, 0, source_image->y - 1);
  184.    
  185.     temp[0] = source_image->data[x+(W*y)].red;
  186.     temp[1] = source_image->data[x+(W*y)].green;
  187.     temp[2] = source_image->data[x+(W*y)].blue;
  188. }
  189.  
  190. void sample_bicubic(PPMImage *source_image, float u, float v, uint8_t sample[]) {
  191.  
  192.     float x = (u * source_image->x)-0.5;
  193.     int xint = (int)x;
  194.     float xfract = x-floor(x);
  195.  
  196.     float y = (v * source_image->y) - 0.5;
  197.     int yint = (int)y;
  198.     float yfract = y - floor(y);
  199.    
  200.     int i;
  201.  
  202.     uint8_t p00[3];
  203.     uint8_t p10[3];
  204.     uint8_t p20[3];
  205.     uint8_t p30[3];
  206.    
  207.     uint8_t p01[3];
  208.     uint8_t p11[3];
  209.     uint8_t p21[3];
  210.     uint8_t p31[3];
  211.  
  212.     uint8_t p02[3];
  213.     uint8_t p12[3];
  214.     uint8_t p22[3];
  215.     uint8_t p32[3];
  216.  
  217.     uint8_t p03[3];
  218.     uint8_t p13[3];
  219.     uint8_t p23[3];
  220.     uint8_t p33[3];
  221.    
  222.     // 1st row
  223.     get_pixel_clamped(source_image, xint - 1, yint - 1, p00);  
  224.     get_pixel_clamped(source_image, xint + 0, yint - 1, p10);
  225.     get_pixel_clamped(source_image, xint + 1, yint - 1, p20);
  226.     get_pixel_clamped(source_image, xint + 2, yint - 1, p30);
  227.    
  228.     // 2nd row
  229.     get_pixel_clamped(source_image, xint - 1, yint + 0, p01);
  230.     get_pixel_clamped(source_image, xint + 0, yint + 0, p11);
  231.     get_pixel_clamped(source_image, xint + 1, yint + 0, p21);
  232.     get_pixel_clamped(source_image, xint + 2, yint + 0, p31);
  233.  
  234.     // 3rd row
  235.     get_pixel_clamped(source_image, xint - 1, yint + 1, p02);
  236.     get_pixel_clamped(source_image, xint + 0, yint + 1, p12);
  237.     get_pixel_clamped(source_image, xint + 1, yint + 1, p22);
  238.     get_pixel_clamped(source_image, xint + 2, yint + 1, p32);
  239.  
  240.     // 4th row
  241.     get_pixel_clamped(source_image, xint - 1, yint + 2, p03);
  242.     get_pixel_clamped(source_image, xint + 0, yint + 2, p13);
  243.     get_pixel_clamped(source_image, xint + 1, yint + 2, p23);
  244.     get_pixel_clamped(source_image, xint + 2, yint + 2, p33);
  245.    
  246.     // interpolate bi-cubically!
  247.     for (i = 0; i < 3; i++) {
  248.  
  249.         float col0 = cubic_hermite(p00[i], p10[i], p20[i], p30[i], xfract);
  250.         float col1 = cubic_hermite(p01[i], p11[i], p21[i], p31[i], xfract);
  251.         float col2 = cubic_hermite(p02[i], p12[i], p22[i], p32[i], xfract);
  252.         float col3 = cubic_hermite(p03[i], p13[i], p23[i], p33[i], xfract);
  253.  
  254.         float value = cubic_hermite(col0, col1, col2, col3, yfract);
  255.  
  256.         CLAMP(value, 0.0f, 255.0f);
  257.  
  258.         sample[i] = (uint8_t)value;
  259.        
  260.         printf("sample[%d]=%d\n",i,sample[i]);      
  261.        
  262.     }
  263.    
  264. }
  265.  
  266. void resize_image(PPMImage *source_image, PPMImage *destination_image, float scale) {
  267.  
  268.     uint8_t sample[3];
  269.     int y, x;
  270.    
  271.     destination_image->x = (long)((float)(source_image->x)*scale);
  272.     destination_image->y = (long)((float)(source_image->y)*scale);
  273.    
  274.     printf("x-width=%d | y-width=%d\n",destination_image->x, destination_image->y);
  275.    
  276.     for (y = 0; y < destination_image->y; y++) {
  277.  
  278.         float v = (float)y / (float)(destination_image->y - 1);
  279.        
  280.         for (x = 0; x < destination_image->x; ++x) {
  281.  
  282.             float u = (float)x / (float)(destination_image->x - 1);
  283.             printf("v=%f\n",v);
  284.             printf("u=%f\n",u);
  285.             sample_bicubic(source_image, u, v, sample);
  286.  
  287.             destination_image->data[x+((destination_image->y)*y)].red   = sample[0];
  288.             destination_image->data[x+((destination_image->y)*y)].green = sample[1];  
  289.             destination_image->data[x+((destination_image->y)*y)].blue  = sample[2];  
  290.         }
  291.     }
  292. }
  293.  
  294. int main() {
  295.    
  296.     float scale = 2.0f;
  297.     PPMImage *source_image;
  298.     PPMImage *destination_image;
  299.    
  300.     printf("starting...\n\n");
  301.    
  302.     if(remove(OUT_PATH) == 0)
  303.         printf("Deleting old image...\n\n");
  304.  
  305.     source_image = readPPM(INP_PATH);
  306.     destination_image = init_destination_image(scale);
  307.    
  308.     resize_image(source_image, destination_image, scale);
  309.  
  310.     writePPM(OUT_PATH, destination_image);
  311.  
  312. }
Add Comment
Please, Sign In to add comment