Version 0.3
[colorize.git] / src / ppm.c
index 7f324bf..f5e6fbb 100755 (executable)
--- a/src/ppm.c
+++ b/src/ppm.c
@@ -6,9 +6,11 @@
 #ifdef WITH_MAGICK
 #include <magick/api.h>
 
-/* load given PPM image to memory. return memory pointer, witdth and height
+int save_depth = 16;
+
+/* load given image to memory. return memory pointer, witdth and height
  * if offset is given, no memory is allocated */
-int load_img(int offset, unsigned char **buffer, int *width, int *height,
+int load_img(int offset, unsigned short **buffer, int *width, int *height,
        const char *filename, int index)
 {
        int rc = -1;
@@ -32,7 +34,7 @@ int load_img(int offset, unsigned char **buffer, int *width, int *height,
        *height = image->rows;
 
        if (offset < 0) {
-               *buffer = (unsigned char *)malloc((*width) * (*height) * 3);
+               *buffer = (unsigned short *)malloc((*width) * (*height) * 3 * sizeof(unsigned short));
                if (!*buffer) {
                        printf("failed to allocate image data\n");
                        goto exit;
@@ -40,7 +42,7 @@ int load_img(int offset, unsigned char **buffer, int *width, int *height,
                offset = 0;
        }
 //     ExportImagePixels(image, 0, 0, *width, *height, "RGB", CharPixel, *buffer, NULL);
-       DispatchImage(image, 0, 0, *width, *height, "RGB", CharPixel, *buffer, NULL);
+       DispatchImage(image, 0, 0, *width, *height, "RGB", ShortPixel, *buffer, NULL);
 
        rc = 0;
 
@@ -58,7 +60,7 @@ exit:
 }
 
 /* save given image */
-int save_img(unsigned char *buffer, int width, int height, const char *filename,
+int save_img(unsigned short *buffer, int width, int height, const char *filename,
        int index)
 {
        int rc = -1;
@@ -73,11 +75,15 @@ int save_img(unsigned char *buffer, int width, int height, const char *filename,
 
        imageinfo->quality = 100;
 
-       image=ConstituteImage(width, height, "RGB", CharPixel, buffer, &exception);
+       image=ConstituteImage(width, height, "RGB", ShortPixel, buffer, &exception);
        if (!image) {
                printf("failed to prepare to write image\n");
                goto exit;
        }
+
+       /* store as 16 bit, if lib and format supports it */
+       image->depth = save_depth;
+
        sprintf(image->filename, filename, index); /* ACHTUNG: nicht imageinfo!!! */
        if (!WriteImage(imageinfo, image)) {
                printf("failed to write image\n");
@@ -102,7 +108,7 @@ exit:
 
 /* load given PPM image to memory. return memory pointer, witdth and height
  * if offset is given, no memory is allocated */
-int load_img(int offset, unsigned char **buffer, int *width, int *height,
+int load_img(int offset, unsigned short **buffer, int *width, int *height,
        const char *filename, int index)
 {
        FILE *fp;
@@ -164,7 +170,7 @@ again3:
                return -1;
        }
        if (offset < 0) {
-               *buffer = (unsigned char *)malloc((*width) * (*height) * 3 * words);
+               *buffer = (unsigned short *)malloc((*width) * (*height) * 3 * words * sizeof(unsigned short));
                if (!*buffer) {
                        printf("failed to allocate image data\n");
                        fclose(fp);
@@ -179,10 +185,18 @@ again3:
                return -1;
        }
 
-       /* convert 16 to 8 bits */
-       if (words == 2) {
-               for (i = 0; i < (*width) * (*height) * 3; i++)
-                       (*buffer)[offset + i] = (*buffer)[offset + i*2];
+       /* convert 8 to 16 bits */
+       if (words == 8) {
+               for (i = (*width) * (*height) * 3 - 1; i >= 0; i--) {
+                       (*buffer)[offset + i] = ((unsigned char *)((*buffer) - offset + (i >> 1)))[0] << 8;
+                       (*buffer)[offset + i] = ((unsigned char *)((*buffer) - offset + (i >> 1)))[1] << 8;
+               }
+       } else {
+               for (i = 0; i < (*width) * (*height) * 3; i++) {
+                       /* correct bit order */
+                       (*buffer)[offset + i] = ((unsigned char *)((*buffer) - offset + i))[0] << 8;
+                       (*buffer)[offset + i] |= ((unsigned char *)((*buffer) - offset + i))[1];
+               }
        }
 
        fclose(fp);
@@ -191,7 +205,7 @@ again3:
 }
 
 /* save given image */
-int save_img(unsigned char *buffer, int width, int height, const char *filename,
+int save_img(unsigned short *buffer, int width, int height, const char *filename,
        int index)
 {
        FILE *fp;
@@ -205,8 +219,13 @@ int save_img(unsigned char *buffer, int width, int height, const char *filename,
                printf("failed to write image\n");
                return -1;
        }
-       fprintf(fp, "P6\n%d %d\n255\n", width, height);
-       rc = fwrite(buffer, width * height * 3, 1, fp);
+       fprintf(fp, "P6\n%d %d\n65535\n", width, height);
+       for (i = 0; i < (*width) * (*height) * 3; i++) {
+               /* correct bit order */
+               rc = fputc(((unsigned char *)((*buffer) - offset + i))[0] >> 8, fp);
+               rc = fputc(((unsigned char *)((*buffer) - offset + i))[1], fp);
+       }
+
        fclose(fp);
 
        return rc;
@@ -216,7 +235,7 @@ int save_img(unsigned char *buffer, int width, int height, const char *filename,
 /* convert an image to a three dimensional array of double
  * the size is: width, height, 3
  */
-void img2array(unsigned char *img, int iw, int ih, double *array, int aw,
+void img2array(unsigned short *img, int iw, int ih, double *array, int aw,
        int ah)
 {
        int x, y;
@@ -225,9 +244,9 @@ void img2array(unsigned char *img, int iw, int ih, double *array, int aw,
 
        for (y = 0; y < ih; y++) {
                for (x = 0; x < iw; x++) {
-                       r = img[(x+iw*y)*3] / 255.0F;
-                       g = img[(x+iw*y)*3+1] / 255.0F;
-                       b = img[(x+iw*y)*3+2] / 255.0F;
+                       r = img[(x+iw*y)*3] / 65535.0F;
+                       g = img[(x+iw*y)*3+1] / 65535.0F;
+                       b = img[(x+iw*y)*3+2] / 65535.0F;
                        array[x+aw*y] = r;
                        array[x+aw*y+plane] = g;
                        array[x+aw*y+plane+plane] = b;
@@ -238,7 +257,7 @@ void img2array(unsigned char *img, int iw, int ih, double *array, int aw,
 /* convert a three dimensional array of double to an image
  * the size is: width, height, 3
  */
-void array2img(double *array, int aw, int ah, unsigned char *img, int iw,
+void array2img(double *array, int aw, int ah, unsigned short *img, int iw,
        int ih)
 {
        int x, y, c;
@@ -250,23 +269,23 @@ void array2img(double *array, int aw, int ah, unsigned char *img, int iw,
                        r = array[x+aw*y];
                        g = array[x+aw*y+plane];
                        b = array[x+aw*y+plane+plane];
-                       c = (r * 255.0F + 0.5F);
+                       c = (r * 65535.0F + 0.5F);
                        if (c < 0)
                                c = 0;
-                       else if (c > 255)
-                               c = 255;
+                       else if (c > 65535)
+                               c = 65535;
                        img[(x+iw*y)*3] = c;
-                       c = (g * 255.0F + 0.5F);
+                       c = (g * 65535.0F + 0.5F);
                        if (c < 0)
                                c = 0;
-                       else if (c > 255)
-                               c = 255;
+                       else if (c > 65535)
+                               c = 65535;
                        img[(x+iw*y)*3+1] = c;
-                       c = (b * 255.0F + 0.5F);
+                       c = (b * 65535.0F + 0.5F);
                        if (c < 0)
                                c = 0;
-                       else if (c > 255)
-                               c = 255;
+                       else if (c > 65535)
+                               c = 65535;
                        img[(x+iw*y)*3+2] = c;
                }
        }