URI:
       twriteppm.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       twriteppm.c (3098B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 #include <memdraw.h>
            5 #include <bio.h>
            6 #include "imagefile.h"
            7 
            8 #define        MAXLINE        70
            9 
           10 /*
           11  * Write data
           12  */
           13 static
           14 char*
           15 writedata(Biobuf *fd, Image *image, Memimage *memimage)
           16 {
           17         char *err;
           18         uchar *data;
           19         int i, x, y, ndata, depth, col, pix, xmask, pmask;
           20         ulong chan;
           21         Rectangle r;
           22 
           23         if(memimage != nil){
           24                 r = memimage->r;
           25                 depth = memimage->depth;
           26                 chan = memimage->chan;
           27         }else{
           28                 r = image->r;
           29                 depth = image->depth;
           30                 chan = image->chan;
           31         }
           32 
           33         /*
           34          * Read image data into memory
           35          * potentially one extra byte on each end of each scan line
           36          */
           37         ndata = Dy(r)*(2+Dx(r)*depth/8);
           38         data = malloc(ndata);
           39         if(data == nil)
           40                 return "WritePPM: malloc failed";
           41         if(memimage != nil)
           42                 ndata = unloadmemimage(memimage, r, data, ndata);
           43         else
           44                 ndata = unloadimage(image, r, data, ndata);
           45         if(ndata < 0){
           46                 err = malloc(ERRMAX);
           47                 if(err == nil)
           48                         return "WritePPM: malloc failed";
           49                 snprint(err, ERRMAX, "WriteGIF: %r");
           50                 free(data);
           51                 return err;
           52         }
           53 
           54         /* Encode and emit the data */
           55         col = 0;
           56         switch(chan){
           57         case GREY1:
           58         case GREY2:
           59         case GREY4:
           60                 pmask = (1<<depth)-1;
           61                 xmask = 7>>drawlog2[depth];
           62                 for(y=r.min.y; y<r.max.y; y++){
           63                         i = (y-r.min.y)*bytesperline(r, depth);
           64                         for(x=r.min.x; x<r.max.x; x++){
           65                                 pix = (data[i]>>depth*((xmask-x)&xmask))&pmask;
           66                                 if(((x+1)&xmask) == 0)
           67                                         i++;
           68                                 col += Bprint(fd, "%d ", pix);
           69                                 if(col >= MAXLINE-(2+1)){
           70                                         Bprint(fd, "\n");
           71                                         col = 0;
           72                                 }else
           73                                         col += Bprint(fd, " ");
           74                         }
           75                 }
           76                 break;
           77         case        GREY8:
           78                 for(i=0; i<ndata; i++){
           79                         col += Bprint(fd, "%d ", data[i]);
           80                         if(col >= MAXLINE-(4+1)){
           81                                 Bprint(fd, "\n");
           82                                 col = 0;
           83                         }else
           84                                 col += Bprint(fd, " ");
           85                 }
           86                 break;
           87         case RGB24:
           88                 for(i=0; i<ndata; i+=3){
           89                         col += Bprint(fd, "%d %d %d", data[i+2], data[i+1], data[i]);
           90                         if(col >= MAXLINE-(4+4+4+1)){
           91                                 Bprint(fd, "\n");
           92                                 col = 0;
           93                         }else
           94                                 col += Bprint(fd, " ");
           95                 }
           96                 break;
           97         default:
           98                 return "WritePPM: can't handle channel type";
           99         }
          100 
          101         return nil;
          102 }
          103 
          104 static
          105 char*
          106 writeppm0(Biobuf *fd, Image *image, Memimage *memimage, Rectangle r, int chan, char *comment)
          107 {
          108         char *err;
          109 
          110         switch(chan){
          111         case GREY1:
          112                 Bprint(fd, "P1\n");
          113                 break;
          114         case GREY2:
          115         case GREY4:
          116         case        GREY8:
          117                 Bprint(fd, "P2\n");
          118                 break;
          119         case RGB24:
          120                 Bprint(fd, "P3\n");
          121                 break;
          122         default:
          123                 return "WritePPM: can't handle channel type";
          124         }
          125 
          126         if(comment!=nil && comment[0]!='\0'){
          127                 Bprint(fd, "# %s", comment);
          128                 if(comment[strlen(comment)-1] != '\n')
          129                         Bprint(fd, "\n");
          130         }
          131         Bprint(fd, "%d %d\n", Dx(r), Dy(r));
          132 
          133         /* maximum pixel value */
          134         switch(chan){
          135         case GREY2:
          136                 Bprint(fd, "%d\n", 3);
          137                 break;
          138         case GREY4:
          139                 Bprint(fd, "%d\n", 15);
          140                 break;
          141         case        GREY8:
          142         case RGB24:
          143                 Bprint(fd, "%d\n", 255);
          144                 break;
          145         }
          146 
          147         err = writedata(fd, image, memimage);
          148 
          149         Bprint(fd, "\n");
          150         Bflush(fd);
          151         return err;
          152 }
          153 
          154 char*
          155 writeppm(Biobuf *fd, Image *image, char *comment)
          156 {
          157         return writeppm0(fd, image, nil, image->r, image->chan, comment);
          158 }
          159 
          160 char*
          161 memwriteppm(Biobuf *fd, Memimage *memimage, char *comment)
          162 {
          163         return writeppm0(fd, nil, memimage, memimage->r, memimage->chan, comment);
          164 }