📄 imgs.cpp
字号:
/********************************************************************** * File: imgs.c (Formerly images.c) * Description: Main image manipulation functions. * Author: Ray Smith * Created: Thu Jun 07 16:25:02 BST 1990 * * (C) Copyright 1990, Hewlett-Packard Ltd. ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** http://www.apache.org/licenses/LICENSE-2.0 ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. * **********************************************************************/#include "mfcpch.h" //precompiled headers#ifdef __MSW32__#include <io.h>#else#include <unistd.h>#endif#include <string.h>#ifdef __UNIX__#include <assert.h>#endif#include "stderr.h"#include "tprintf.h"#include "imgerrs.h"#include "memry.h"#include "imgs.h"#include "imgio.h"#include "imgunpk.h"#define FIXED_COLOURS 32 /*number of fixed colours */#define MIN_4BIT 48 /*4bpp range */#define MAX_4BIT 64#define MIN_6BIT 64 /*6bpp range */#define MAX_6BIT 128#define BLACK_PIX 0static UINT8 grey_scales[FIXED_COLOURS] = { 0, 255, 76, 227, 151, 179, 28, 104, 149, 72, 215, 67, 53, 44, 156, 137, 110, 153, 79, 181, 166, 218, 55, 81, 129, 105, 179, 149, 168, 69, 84, 126};#define EXTERNEXTERN INT_VAR (image_default_resolution, 300, "Image resolution dpi");/********************************************************************** * IMAGE * * Contructor for an IMAGE class. Makes the image definitely illegal. **********************************************************************/IMAGE::IMAGE() { //construct an image bpp = 0; //all illegal fd = -1; image = NULL; photo_interp = 1; res = image_default_resolution;}/********************************************************************** * IMAGE::operator= * * Assign an IMAGE to another. The dest becomes the owner of the memory. **********************************************************************/IMAGE & IMAGE::operator= ( //assignmentIMAGE & source //source image) { destroy(); bpp = source.bpp; photo_interp = source.photo_interp; bps = source.bps; bytespp = (bpp + 7) / 8; lineskip = source.lineskip; //copy everything captured = source.captured; xsize = source.xsize; ysize = source.ysize; res = source.res; image = source.image; xdim = source.xdim; bufheight = source.bufheight; fd = source.fd; reader = source.reader; ymin = source.ymin; ymax = source.ymax; source.captured = TRUE; //source now captured source.fd = -1; return *this;}/********************************************************************** * create * * Create an image (allocate memory) of a specific size and bpp. **********************************************************************/INT8 IMAGE::create( //get rest of image INT32 x, //x size required INT32 y, //ysize required INT8 bits_per_pixel //bpp required ) { UINT8 *pixels; //memory for image xdim = check_legal_image_size (x, y, bits_per_pixel); if (xdim < 0) return -1; pixels = (UINT8 *) alloc_big_zeros ((size_t) (xdim * y * sizeof (UINT8))); if (pixels == NULL) { MEMORY_OUT.error ("IMAGE::create", ABORT, "Size=(%d,%d)", xdim, y); return -1; } //allocate to image this->capture (pixels, x, y, bits_per_pixel); captured = FALSE; res = image_default_resolution; return 0; //success}/********************************************************************** * destroy * * Destroy an image, freeing memory and closing any open file. **********************************************************************/void IMAGE::destroy() { //get rid of image if (image != NULL && !captured) { free_big_mem(image); } image = NULL; if (fd >= 0) { close(fd); fd = -1; } bpp = 0;}/********************************************************************** * capture * * Assign a given memory area to an image to use as an image of * given size and bpp. **********************************************************************/INT8 IMAGE::capture( //get rest of image UINT8 *pixels, //image memory INT32 x, //x size required INT32 y, //ysize required INT8 bits_per_pixel //bpp required ) { destroy(); xdim = check_legal_image_size (x, y, bits_per_pixel); if (xdim < 0) return -1; xsize = x; ysize = y; bufheight = y; bpp = bits_per_pixel; bps = bpp == 24 ? 8 : bpp; photo_interp = 1; bytespp = (bpp + 7) / 8; image = pixels; //assign image area ymin = 0; ymax = bufheight; //read it all captured = TRUE; res = image_default_resolution; return 0; //success}/********************************************************************** * pixel * * Get a single pixel out of the image. **********************************************************************/UINT8 IMAGE::pixel( //get rest of image INT32 x, //x coord INT32 y //y coord ) { if (x < 0) x = 0; //silently clip else if (x >= xsize) x = xsize - 1; if (y < 0) y = 0; else if (y >= ysize) y = ysize - 1; check_legal_access (x, y, 1); switch (bpp) { case 5: case 6: case 8: return image[(ymax - 1 - y) * xdim + x]; case 4: return bpp4table[image[(ymax - 1 - y) * xdim + x / 2]][x & 1]; case 2: return bpp2table[image[(ymax - 1 - y) * xdim + x / 4]][x & 3]; case 1: return bpp1table[image[(ymax - 1 - y) * xdim + x / 8]][x & 7]; default: tprintf ("Unexpected bits per pixel %d\n", bpp); return 0; }}/********************************************************************** * check_legal_image_size * * Check that the supplied image sizes are legal. If they are, * the xdim is returned, else -1. **********************************************************************/INT32 check_legal_image_size( //get rest of image INT32 x, //x size required INT32 y, //ysize required INT8 bits_per_pixel //bpp required ) { if (x <= 0 || y <= 0) { BADIMAGESIZE.error ("check_legal_image_size", LOG, "(%d,%d)", x, y); return -1; //failed } if (bits_per_pixel != 1 && bits_per_pixel != 2 && bits_per_pixel != 4 && bits_per_pixel != 5 && bits_per_pixel != 6 && bits_per_pixel != 8 && bits_per_pixel != 24) { BADBPP.error ("check_legal_image_size", LOG, "%d", bits_per_pixel); return -1; } //bytes per line return COMPUTE_IMAGE_XDIM (x, bits_per_pixel);}/********************************************************************** * copy_sub_image * * Copy a portion of one image to a portion of another image. * If the bpps are different, the position of the most significant * bit is preserved. **********************************************************************/DLLSYM void copy_sub_image( //copy rectangle IMAGE *source, //source image INT32 xstart, //start coords INT32 ystart, INT32 xext, //extent to copy INT32 yext, IMAGE *dest, //destination image INT32 xdest, //destination coords INT32 ydest, BOOL8 adjust_grey //shift to new bpp ) { IMAGELINE copyline; //copy of line UINT8 *copy; //source pointer INT8 shift; //shift factor INT32 pixel; //pixel index INT32 y; //line index INT32 yoffset; //current adjusted offset INT32 bytesize; //no of bytes to copy INT32 srcppb; //pixels per byte BOOL8 aligned; if (xstart < 0 || ystart < 0 || xdest < 0 || ydest < 0) return; if (xext <= 0) xext = source->xsize; //default to all if (xext > source->xsize - xstart) //clip to smallest xext = source->xsize - xstart; if (xext > dest->xsize - xdest) xext = dest->xsize - xdest; if (yext <= 0) yext = source->ysize; //default to all if (yext > source->ysize - ystart) //clip to smallest yext = source->ysize - ystart; if (yext > dest->ysize - ydest) yext = dest->ysize - ydest; if (xext <= 0 || yext <= 0) return; //nothing to do srcppb = 8 / source->bpp; //pixels per byte if (source->bpp == dest->bpp || !adjust_grey) shift = 0; //no adjustment else { shift = source->bps - dest->bps; if (shift < 0) shift = -shift; //keep positive } aligned = source->bpp == dest->bpp; if (aligned && srcppb != 0) { aligned = xstart % srcppb == 0 && xdest % srcppb == 0 && (xext % srcppb == 0 || xdest + xext == dest->xsize); } for (y = 0; y < yext; y++) { if (ystart >= ydest) yoffset = y; //top down else yoffset = yext - y - 1; //bottom up source->check_legal_access (xstart, ystart + yoffset, xext); dest->check_legal_access (xdest, ydest + yoffset, xext); if (aligned) { bytesize = COMPUTE_IMAGE_XDIM (xext, source->bpp); //get bytes per line if (srcppb == 0) //do cheap move memmove (dest->image + (dest->ymax - 1 - ydest - yoffset) * dest->xdim + xdest * 3, source->image + (source->ymax - 1 - ystart - yoffset) * source->xdim + xstart * 3, (unsigned) bytesize); else //do cheap move memmove (dest->image + (dest->ymax - 1 - ydest - yoffset) * dest->xdim + xdest / srcppb, source->image + (source->ymax - 1 - ystart - yoffset) * source->xdim + xstart / srcppb, (unsigned) bytesize); } else { if (shift == 0) { source->fast_get_line (xstart, ystart + yoffset, xext, ©line); } else if (source->bpp < dest->bpp) { source->get_line (xstart, ystart + yoffset, xext, ©line, 0); if (source->bpp <= shift && (source->bpp == 1 || source->bpp == 4)) { if (source->bpp == 1) { for (pixel = 0, copy = copyline.pixels; pixel < xext; pixel++, copy++) if (*copy) *copy = 0xff; } else { for (pixel = 0, copy = copyline.pixels; pixel < xext; pixel++, copy++) //scale up *copy = (*copy << shift) | *copy; } } else { for (pixel = 0, copy = copyline.pixels; pixel < xext; pixel++) *copy++ <<= shift; //scale up } } else { source->get_line (xstart, ystart + yoffset, xext, ©line, 0); if (source->bpp == 24) { for (pixel = 0, copy = copyline.pixels + 1; pixel < xext; pixel++) { *copy >>= shift; copy += 3; } } else { for (pixel = 0, copy = copyline.pixels; pixel < xext; pixel++) *copy++ >>= shift; //scale down } } dest->put_line (xdest, ydest + yoffset, xext, ©line, 0); } }}/********************************************************************** * enlarge_sub_image * * Enlarge a portion of one image to a portion of another image. * If the bpps are different, the position of the most significant * bit is preserved. **********************************************************************/DLLSYM void enlarge_sub_image( //enlarge rectangle IMAGE *source, //source image INT32 xstart, //scaled start coords INT32 ystart, IMAGE *dest, //destination image INT32 xdest, //dest coords INT32 ydest, INT32 xext, //destination extent INT32 yext, INT32 scale, //scale factor BOOL8 adjust_grey //shift to new bpp ) { INT8 shift; //shift factor UINT8 pixel; //current pixel INT32 srcext; //source extent INT32 xoffset; //column index INT32 yoffset; //line index INT32 xindex, yindex; //index in super pixel INT32 startxindex; //initial x index INT32 xscale; //x scale factor
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -