?? image.c
字號:
unsigned el_size; char *startString; char *startTag; boolean maxvalPresent; int i; char *p; char commentBuf[PBM_MAX_LINELEN]; assert(outFile != (FILE *)NULL); assert(im != (void *)NULL); assert(header != (ImageHeader *)NULL); /* * Get a pointer to the data area, the size of each element, and * the format of the header. The header may include a dummy entry * (some of the p*m formats have a maxval entry in the header - we * just use the maximum value we can represent). */ switch (header->tag) { case IMAGE_GRAY: { rect = (void *) &(((((GrayImage)im)->data)[header->ybase])[header->xbase]); el_size = sizeof(unsigned char); /* This is the start of an appropriate PGM file header */ startTag = TAG_GRAY; startString = "%d %d %d\n"; maxvalPresent = TRUE; break; } case IMAGE_FLOAT: { rect = (void *) &(((((FloatImage)im)->data)[header->ybase])[header->xbase]); el_size = sizeof(float); /* * Not a PGM or PBM or PanythingM header - make it look strange. */ startTag = TAG_FLOAT; startString = "%d %d\n"; maxvalPresent = FALSE; break; } case IMAGE_RGB: { rect = (void *) &(((((RGBImage)im)->data)[header->ybase])[header->xbase]); el_size = sizeof(RGB); /* A PPM header */ startTag = TAG_RGB; startString = "%d %d %d\n"; maxvalPresent = TRUE; break; } case IMAGE_DOUBLE: { rect = (void *) &(((((DoubleImage)im)->data)[header->ybase])[header->xbase]); el_size = sizeof(double); /* * Not a PGM or PBM or PanythingM header - make it look strange. */ startTag = TAG_DOUBLE; startString = "%d %d\n"; maxvalPresent = FALSE; break; } case IMAGE_BINARY: { rect = (void *) &(((((BinaryImage)im)->data)[header->ybase])[header->xbase]); el_size = 0; startTag = TAG_BINARY; startString = "%d %d\n"; maxvalPresent = FALSE; break; } case IMAGE_LONG: { rect = (void *) &(((((LongImage)im)->data)[header->ybase])[header->xbase]); el_size = sizeof(long); /* * Not a PGM or PBM or PanythingM header - make it look strange. */ startTag = TAG_LONG; startString = "%d %d\n"; maxvalPresent = FALSE; break; } case IMAGE_PTR: { panic("attempt to save pointer image"); break; } case IMAGE_SHORT: { rect = (void *) &(((((ShortImage)im)->data)[header->ybase])[header->xbase]); el_size = sizeof(short); /* * Not a PGM or PBM or PanythingM header - make it look strange. */ startTag = TAG_SHORT; startString = "%d %d\n"; maxvalPresent = FALSE; break; } default: { panic("bad image tag"); } } /* Write out the tag, and comments if any */ if (fprintf(outFile, "%s\n", startTag) == EOF) { return(-1); } if (header->comment != (char *)NULL) { p = header->comment; while (*p != '\0') { /* Copy a line into commentBuf */ for (i = 0; (i < PBM_MAX_LINELEN) && (p[i] != '\n') && (p[i] != '\0'); i++) { commentBuf[i] = p[i]; } if (i == PBM_MAX_LINELEN) { /* The line was too long - search back for whitespace */ for (i = PBM_MAX_LINELEN - 1; (i >= 0) && (!isspace(commentBuf[i])); i--) { } if (i < 0) { /* There was no whitespace. Break it how we like it... */ commentBuf[PBM_MAX_LINELEN - 1] = '\0'; i = PBM_MAX_LINELEN - 1; } else { /* Break at the whitespace */ commentBuf[i] = '\0'; i++; } } else { commentBuf[i] = '\0'; } /* * At this point, commentBuf contains i characters to be * printed. */ if (fprintf(outFile, "#%s\n", commentBuf) == EOF) { return(-1); } /* Advance the pointer */ p += i; if (*p == '\n') { p++; } } } /* Write out the header info */ if (maxvalPresent) { if (fprintf(outFile, startString, header->width, header->height, COLRNG - 1) == EOF) { return(-1); } } else { if (fprintf(outFile, startString, header->width, header->height) == EOF) { return(-1); } } /* Write out the data block */ if (header->tag != IMAGE_BINARY) { if (fwrite((char *)rect, el_size, (header->width * header->height), outFile) != header->width * header->height) { return(-1); } } else { /* For binary images, have to write differently */ register int i, j, c, bitsleft, height, width; height = (int)header->height + header->ybase; width = (int)header->width + header->xbase; for (i = header->ybase; i < height; i++) { bitsleft = 8; c = 0; for (j = header->xbase; j < width; j++) { --bitsleft; if (imRef((BinaryImage)im, j, i)) { c |= 1 << bitsleft; } if ((bitsleft == 0) || (j == width - 1)) { if (putc(c, outFile) == EOF) { return(-1); } bitsleft = 8; c = 0; } } } } /* and successfully return */ return(0); }void *im_Dup_(void *im, ImageHeader *header, boolean copycomment){ void *dup; unsigned el_size; char *oldbase; char *newbase; ImageHeader *newheader; assert(im != (void *)NULL); assert(header != (ImageHeader *)NULL); /* Make a copy. */ dup = imNewOffset(header->tag, header->width, header->height, header->xbase, header->ybase); if (dup == (void *)NULL) { return((void *)NULL); } switch(header->tag) { case IMAGE_GRAY: { oldbase = (void *) &(((GrayImage)im)->data[header->ybase][header->xbase]); newbase = (void *) &(((GrayImage)dup)->data[header->ybase][header->xbase]); el_size = sizeof(unsigned char); newheader = ((GrayImage)dup)->header; break; } case IMAGE_FLOAT: { oldbase = (void *) &(((FloatImage)im)->data[header->ybase][header->xbase]); newbase = (void *) &(((FloatImage)dup)->data[header->ybase][header->xbase]); el_size = sizeof(float); newheader = ((FloatImage)dup)->header; break; } case IMAGE_RGB: { oldbase = (void *) &(((RGBImage)im)->data[header->ybase][header->xbase]); newbase = (void *) &(((RGBImage)dup)->data[header->ybase][header->xbase]); el_size = sizeof(RGB); newheader = ((RGBImage)dup)->header; break; } case IMAGE_DOUBLE: { oldbase = (void *) &(((DoubleImage)im)->data[header->ybase][header->xbase]); newbase = (void *) &(((DoubleImage)dup)->data[header->ybase][header->xbase]); el_size = sizeof(double); newheader = ((DoubleImage)dup)->header; break; } case IMAGE_BINARY: { oldbase = (void *) &(((BinaryImage)im)->data[header->ybase][header->xbase]); newbase = (void *) &(((BinaryImage)dup)->data[header->ybase][header->xbase]); el_size = sizeof(char); newheader = ((BinaryImage)dup)->header; break; } case IMAGE_LONG: { oldbase = (void *) &(((LongImage)im)->data[header->ybase][header->xbase]); newbase = (void *) &(((LongImage)dup)->data[header->ybase][header->xbase]); el_size = sizeof(long); newheader = ((LongImage)dup)->header; break; } case IMAGE_PTR: { oldbase = (void *) &(((PtrImage)im)->data[header->ybase][header->xbase]); newbase = (void *) &(((PtrImage)dup)->data[header->ybase][header->xbase]); el_size = sizeof(void *); newheader = ((PtrImage)dup)->header; break; } case IMAGE_SHORT: { oldbase = (void *) &(((ShortImage)im)->data[header->ybase][header->xbase]); newbase = (void *) &(((ShortImage)dup)->data[header->ybase][header->xbase]); el_size = sizeof(short); newheader = ((ShortImage)dup)->header; break; } default: { panic("bad image tag"); } } /* Copy the comment, if any, and if we're supposed to */ if (copycomment && (header->comment != (char *)NULL)) { newheader->comment = strdup(header->comment); if (newheader->comment == (char *)NULL) { /* Failed to copy */ im_Free_(dup, newheader); return((void *)NULL); } } /* Do the copy */ (void)memcpy(newbase, oldbase, (el_size * header->width * header->height)); return(dup); }void *im_Promote_(void *im, ImageHeader *header, ImageType promoteto){ ImageType origtype; void *newim; assert(im != (void *)NULL); assert(header != (ImageHeader *)NULL); origtype = header->tag; if (!convertTable[origtype][promoteto].isPromotion) { /* They just requested a non-promotion. Bad... */ panic("non-promotion request made to imPromote()"); } assert(convertTable[origtype][promoteto].convertFunc != (void * (*)(void *))NULL); newim = (*convertTable[origtype][promoteto].convertFunc)(im); return(newim); }voidimSetPromotion(ImageType promotefrom, ImageType promoteto, double slope, double offset){ if (!convertTable[promotefrom][promoteto].isPromotion) { panic("attempt made to imSetPromotion a non-promotion conversion"); } convertTable[promotefrom][promoteto].slope = slope; convertTable[promotefrom][promoteto].offset = offset; }void *im_Demote_(void *im, ImageHeader *header, ImageType demoteto){ ImageType origtype; void *newim; assert(im != (void *)NULL); assert(header != (ImageHeader *)NULL); origtype = header->tag; if (convertTable[origtype][demoteto].isPromotion) { /* They just requested a promotion. Bad... */ panic("promotion request made to imDemote()"); } else if (convertTable[origtype][demoteto].convertFunc == (void * (*)(void *))NULL) { panic("impossible request made to imDemote()"); } newim = (*convertTable[origtype][demoteto].convertFunc)(im); return(newim); }void *im_Convert_(void *im, ImageHeader *header, ImageType convertto){ ImageType origtype; assert(im != (void *)NULL); assert(header != (ImageHeader *)NULL); origtype = header->tag; if (origtype == convertto) { /* They really just want a copy */ return(im_Dup_(im, header, FALSE)); } else if (convertTable[origtype][convertto].isPromotion) { /* It's a promotion */ return(im_Promote_(im, header, convertto)); } else { /* It's a demotion, or illegal - let imDemote handle it */ return(im_Demote_(im, header, convertto)); } }booleanim_SetComment_(void *im, ImageHeader *header, char *newcomment){ char *newcopy; assert(im != (void *)NULL); assert(header != (ImageHeader *)NULL); if (newcomment != (char *)NULL) { newcopy = strdup(newcomment); if (newcopy == (char *)NULL) { return(FALSE); } } else { newcopy = (char *)NULL; } if (header->comment != (char *)NULL) { /* Free the old comment */ free((void *)header->comment); } header->comment = newcopy; return(TRUE); }/* * Here are the actual file-reading routines. * * Each one is passed a FILE * and an ImageHeader **. It knows that the file * stream is positioned immediately after a P?M (or similar) magic number, * and implicitly what that magic number was (i.e. what form the file will * take). It then reads the file, creates an Image of the appropriate type, * and returns it as its return value, putting a pointer to its ImageHeader * into *readimHeader. */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -