result_t Image::convert(int32_t color, AsyncEvent *ac) { if (!m_image) return CHECK_ERROR(CALL_E_INVALID_CALL); if (!ac) return CHECK_ERROR(CALL_E_NOSYNC); if (color != gd_base::_TRUECOLOR && color != gd_base::_PALETTE) return CHECK_ERROR(CALL_E_INVALIDARG); if (color == gd_base::_TRUECOLOR && !gdImageTrueColor(m_image)) { setExtMemory(-1); gdImagePaletteToTrueColor(m_image); setExtMemory(); } else if (color == gd_base::_PALETTE && gdImageTrueColor(m_image)) { setExtMemory(-1); gdImageTrueColorToPalette(m_image, 1, 256); setExtMemory(); } else return CHECK_ERROR(CALL_E_INVALID_CALL); return 0; }
/* This routine reads a png-file from disk and puts it into buff in a format the LCD understands. (basically 16-bit rgb) */ int readpic(char* filename, char* buff) { FILE *in; gdImagePtr im; int x,y; int c,r,g,b; in=fopen(filename,"rb"); if (in==NULL) return 0; //Should try other formats too im=gdImageCreateFromPng(in); fclose(in); if (im==NULL) return 0; for (y=0; y<128; y++) { for (x=0; x<128; x++) { c = gdImageGetPixel(im, x, y); if (gdImageTrueColor(im) ) { r=gdTrueColorGetRed(c); g=gdTrueColorGetGreen(c); b=gdTrueColorGetBlue(c); } else { r=gdImageRed(im,c); g=gdImageGreen(im,c); b=gdImageBlue(im,c); } r>>=3; g>>=2; b>>=3; c=(r<<11)+(g<<5)+b; buff[x*2+y*256]=(c>>8); buff[x*2+y*256+1]=(c&255); } } gdImageDestroy(im); return 1; }
result_t Image::get_type(int32_t &retVal) { if (!m_image) return CHECK_ERROR(CALL_E_INVALID_CALL); retVal = gdImageTrueColor(m_image) ? gd_base::_TRUECOLOR : gd_base::_PALETTE; return 0; }
gdImagePtr rotatePixmapGD(gdImagePtr img, double angle_rad) { gdImagePtr rimg = NULL; double cos_a, sin_a; double x1 = 0.0, y1 = 0.0; /* destination rectangle */ double x2 = 0.0, y2 = 0.0; double x3 = 0.0, y3 = 0.0; double x4 = 0.0, y4 = 0.0; long minx, miny, maxx, maxy; int width=0, height=0; /* int color; */ sin_a = sin(angle_rad); cos_a = cos(angle_rad); /* compute distination rectangle (x1,y1 is known) */ x1 = 0 ; y1 = 0 ; x2 = img->sy * sin_a; y2 = -img->sy * cos_a; x3 = (img->sx * cos_a) + (img->sy * sin_a); y3 = (img->sx * sin_a) - (img->sy * cos_a); x4 = (img->sx * cos_a); y4 = (img->sx * sin_a); minx = (long) MS_MIN(x1,MS_MIN(x2,MS_MIN(x3,x4))); miny = (long) MS_MIN(y1,MS_MIN(y2,MS_MIN(y3,y4))); maxx = (long) MS_MAX(x1,MS_MAX(x2,MS_MAX(x3,x4))); maxy = (long) MS_MAX(y1,MS_MAX(y2,MS_MAX(y3,y4))); width = (int)ceil(maxx-minx); height = (int)ceil(maxy-miny); /* create the new image based on the computed width/height */ if (gdImageTrueColor(img)) { rimg = gdImageCreateTrueColor(width, height); gdImageAlphaBlending(rimg, 0); gdImageFilledRectangle(rimg, 0, 0, width, height, gdImageColorAllocateAlpha(rimg, 0, 0, 0, gdAlphaTransparent)); } else { int tc = gdImageGetTransparent(img); rimg = gdImageCreate(width, height); if(tc != -1) gdImageColorTransparent(rimg, gdImageColorAllocate(rimg, gdImageRed(img, tc), gdImageGreen(img, tc), gdImageBlue(img, tc))); } if(!rimg) { msSetError(MS_GDERR,"failed to create rotated pixmap","rotatePixmapGD()"); return NULL; } gdImageCopyRotated (rimg, img, width*0.5, height*0.5, 0, 0, gdImageSX(img), gdImageSY(img), angle_rad*MS_RAD_TO_DEG); return rimg; }
int v4lDecodeImage(v4lT* s, v4lBufT* decoded, v4lBufT* encoded, int w, int h, bool scale) { if( s->fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV ) { if( scale ) fprintf(stderr, "Warning: scaling YUYV input is not implemented yet, will pad instead\n"); if( decoded->length < encoded->length*2 ) fprintf(stderr, "Decode buffer is too small to hold the decoded image\n"); //v4lDecodeYUYV uses w/h of encoded/decoded to calculate padding (if necessary) encoded->w = s->fmt.fmt.pix.width; encoded->h = s->fmt.fmt.pix.height; decoded->w = w ? w : encoded->w; decoded->h = h ? h : encoded->h; return v4lDecodeYUYV(decoded, encoded); } if( s->fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG ) { gdImagePtr img = v4lDecodeMJPEG(encoded->data, encoded->length); if( !img || !gdImageTrueColor(img) ) { fprintf(stderr, "Could not decode jpeg image, conversion error?\n"); return 1; } int imgWidth = gdImageSX(img); int imgHeight = gdImageSY(img); if( w && h && (imgWidth != w || imgHeight != h) && scale ) { //scale image if necessary, padding will be done below gdImagePtr src = img; img = gdImageCreateTrueColor(w, h); gdImageCopyResized(img, src, 0, 0, 0, 0, w, h, imgWidth, imgHeight); gdImageDestroy(src); imgWidth = w; imgHeight = h; } decoded->w = imgWidth; decoded->h = imgHeight; if( decoded->length < decoded->w*decoded->h*4 ) { fprintf(stderr, "Decode buffer is too small to hold the decoded image\n"); return 1; } //copy pixel data (and implicitly pad with black borders) for( int y = 0; y < imgHeight; y++ ) for( int x = 0; x < imgWidth; x++ ) *(((uint32_t*)decoded->data)+y*decoded->w+x) = gdImageGetPixel(img, x, y); gdImageDestroy(img); return 0; } fprintf(stderr, "Could not decode image. No supported format.\n"); return 1; }
/** * Function: gdImageCrop * * Crop an image to a given rectangle * * Parameters: * src - The image. * crop - The cropping rectangle, see <gdRect>. * * Returns: * The newly created cropped image, or NULL on failure. * * See also: * - <gdImageCropAuto> * - <gdImageCropThreshold> */ BGD_DECLARE(gdImagePtr) gdImageCrop(gdImagePtr src, const gdRect *crop) { gdImagePtr dst; int alphaBlendingFlag; if (gdImageTrueColor(src)) { dst = gdImageCreateTrueColor(crop->width, crop->height); } else { dst = gdImageCreate(crop->width, crop->height); } if (!dst) return NULL; alphaBlendingFlag = dst->alphaBlendingFlag; gdImageAlphaBlending(dst, gdEffectReplace); gdImageCopy(dst, src, 0, 0, crop->x, crop->y, crop->width, crop->height); gdImageAlphaBlending(dst, alphaBlendingFlag); return dst; }
/* This routine reads a png-file from disk and puts it into buff in a format lib understands. (basically 24-bit rgb) */ int sendpic(st2205_handle *h, char* filename) { FILE *in; gdImagePtr im; unsigned char* pixels; int x,y; int p=0; unsigned int c,r,g,b; pixels=malloc(h->width*h->height*3); in=fopen(filename,"rb"); if (in==NULL) return 0; //Should try other formats too im=gdImageCreateFromPng(in); fclose(in); if (im==NULL) { printf("%s: not a png-file.\n",filename); return 0; } for (y=0; y<h->width; y++) { for (x=0; x<h->height; x++) { c = gdImageGetPixel(im, x, y); if (gdImageTrueColor(im) ) { r=gdTrueColorGetRed(c); g=gdTrueColorGetGreen(c); b=gdTrueColorGetBlue(c); } else { r=gdImageRed(im,c); g=gdImageGreen(im,c); b=gdImageBlue(im,c); } // pixels[p++]=0xff; // pixels[p++]=0; // pixels[p++]=0; pixels[p++]=r; pixels[p++]=g; pixels[p++]=b; } } st2205_send_data(h,pixels); gdImageDestroy(im); return 1; }
result_t Image::rotate(int32_t dir) { if (dir != gd_base::_LEFT && dir != gd_base::_RIGHT) return CHECK_ERROR(CALL_E_INVALIDARG); int32_t sx = gdImageSX(m_image); int32_t sy = gdImageSY(m_image); int32_t i, j; gdImagePtr newImage; if (gdImageTrueColor(m_image)) newImage = gdImageCreateTrueColor(sy, sx); else { newImage = gdImageCreate(sy, sx); gdImagePaletteCopy(newImage, m_image); } gdImageColorTransparent(newImage, gdImageGetTransparent(m_image)); if (dir == gd_base::_LEFT) { for (i = 0; i < sx; i++) for (j = 0; j < sy; j++) gdImageSetPixel(newImage, j, sx - i - 1, gdImageGetPixel(m_image, i, j)); } else { for (i = 0; i < sx; i++) for (j = 0; j < sy; j++) gdImageSetPixel(newImage, sy - j - 1, i, gdImageGetPixel(m_image, i, j)); } setExtMemory(-1); gdImageDestroy(m_image); m_image = newImage; setExtMemory(); return 0; }
result_t Image::New(int32_t width, int32_t height, obj_ptr<Image> &retVal) { if (width <= 0 || height <= 0) return CHECK_ERROR(CALL_E_INVALIDARG); obj_ptr<Image> img = new Image(); if (gdImageTrueColor(m_image)) img->m_image = gdImageCreateTrueColor(width, height); else img->m_image = gdImageCreate(width, height); gdImagePaletteCopy(img->m_image, m_image); gdImageColorTransparent(img->m_image, gdImageGetTransparent(m_image)); img->setExtMemory(); retVal = img; return 0; }
/** * Function: gdImageCropThreshold * * Crop an image using a given color * * The _threshold_ defines the tolerance to be used while comparing the image * color and the color to crop. The method used to calculate the color * difference is based on the color distance in the RGB(A) cube. * * Parameters: * im - The image. * color - The crop color. * threshold - The crop threshold. * * Returns: * The newly created cropped image, or NULL on failure. * * See also: * - <gdImageCrop> * - <gdImageCropAuto> */ BGD_DECLARE(gdImagePtr) gdImageCropThreshold(gdImagePtr im, const unsigned int color, const float threshold) { const int width = gdImageSX(im); const int height = gdImageSY(im); int x,y; int match; gdRect crop; crop.x = 0; crop.y = 0; crop.width = 0; crop.height = 0; /* Pierre: crop everything sounds bad */ if (threshold > 100.0) { return NULL; } if (!gdImageTrueColor(im) && color >= gdImageColorsTotal(im)) { return NULL; } /* TODO: Add gdImageGetRowPtr and works with ptr at the row level * for the true color and palette images * new formats will simply work with ptr */ match = 1; for (y = 0; match && y < height; y++) { for (x = 0; match && x < width; x++) { match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0; } } /* Whole image would be cropped > bye */ if (match) { return NULL; } crop.y = y - 1; match = 1; for (y = height - 1; match && y >= 0; y--) { for (x = 0; match && x < width; x++) { match = (gdColorMatch(im, color, gdImageGetPixel(im, x, y), threshold)) > 0; } } crop.height = y - crop.y + 2; match = 1; for (x = 0; match && x < width; x++) { for (y = 0; match && y < crop.y + crop.height; y++) { match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0; } } crop.x = x - 1; match = 1; for (x = width - 1; match && x >= 0; x--) { for (y = 0; match && y < crop.y + crop.height; y++) { match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0; } } crop.width = x - crop.x + 2; return gdImageCrop(im, &crop); }
result_t Image::getData(int32_t format, int32_t quality, obj_ptr<Buffer_base> &retVal, AsyncEvent *ac) { if (!m_image) return CHECK_ERROR(CALL_E_INVALID_CALL); if (!ac) return CHECK_ERROR(CALL_E_NOSYNC); int32_t size = 0; void *data = NULL; int32_t sx = gdImageSX(m_image); int32_t sy = gdImageSY(m_image); int32_t i, j; int32_t trans = -1; if (gdImageTrueColor(m_image)) { for (i = 0; i < sx && trans == -1; i ++) for (j = 0; j < sy && trans == -1; j++) if ((gdImageGetPixel(m_image, i, j) & 0xff000000) != 0) trans = 0; } else trans = gdImageGetTransparent(m_image); gdImagePtr nowImage = m_image; if (trans != -1) { if (format != gd_base::_PNG) { if (gdImageTrueColor(m_image)) nowImage = gdImageCreateTrueColor(sx, sy); else { nowImage = gdImageCreate(sx, sy); gdImagePaletteCopy(nowImage, m_image); } gdImageFilledRectangle(nowImage, 0, 0, sx, sy, gdImageColorAllocate(nowImage, 255, 255, 255)); gdImageCopy(nowImage, m_image, 0, 0, 0, 0, sx, sy); } else if (gdImageTrueColor(m_image)) gdImageSaveAlpha(m_image, 1); } switch (format) { case gd_base::_GIF: data = gdImageGifPtr(nowImage, &size); break; case gd_base::_PNG: data = gdImagePngPtr(nowImage, &size); break; case gd_base::_JPEG: { unsigned char *ed_data = NULL; uint32_t ed_size = 0; data = gdImageJpegPtr(nowImage, &size, quality, ed_data, ed_size); if (ed_data) free(ed_data); break; } case gd_base::_TIFF: data = gdImageTiffPtr(nowImage, &size); break; case gd_base::_BMP: data = gdImageBmpPtr(nowImage, &size, 1); break; case gd_base::_WEBP: data = gdImageWebpPtrEx(nowImage, &size, quality); break; } if (nowImage != m_image) gdImageDestroy(nowImage); if (data == NULL) return CHECK_ERROR(CALL_E_INVALIDARG); retVal = new Buffer(std::string((char *) data, size)); gdFree(data); return 0; }
static int puzzle_getview_from_gdimage(PuzzleContext * const context, PuzzleView * const view, gdImagePtr gdimage) { unsigned int x, y; const unsigned int x0 = 0U, y0 = 0U; unsigned int x1, y1; unsigned char *maptr; int pixel; view->map = NULL; view->width = (unsigned int) gdImageSX(gdimage); view->height = (unsigned int) gdImageSY(gdimage); view->sizeof_map = (size_t) (view->width * view->height); if (view->width > context->puzzle_max_width || view->height > context->puzzle_max_height) { return -1; } if (view->sizeof_map <= (size_t) 0U || INT_MAX / view->width < view->height || SIZE_MAX / view->width < view->height || (unsigned int) view->sizeof_map != view->sizeof_map) { puzzle_err_bug(__FILE__, __LINE__); } x1 = view->width - 1U; y1 = view->height - 1U; if (view->width <= 0U || view->height <= 0U) { puzzle_err_bug(__FILE__, __LINE__); } if ((view->map = calloc(view->sizeof_map, sizeof *view->map)) == NULL) { return -1; } if (x1 > INT_MAX || y1 > INT_MAX) { /* GD uses "int" for coordinates */ puzzle_err_bug(__FILE__, __LINE__); } maptr = view->map; x = x1; if (gdImageTrueColor(gdimage) != 0) { do { y = y1; do { pixel = gdImageGetTrueColorPixel(gdimage, (int) x, (int) y); *maptr++ = (unsigned char) ((gdTrueColorGetRed(pixel) * 77 + gdTrueColorGetGreen(pixel) * 151 + gdTrueColorGetBlue(pixel) * 28 + 128) / 256); } while (y-- != y0); } while (x-- != x0); } else { do { y = y1; do { pixel = gdImagePalettePixel(gdimage, x, y); *maptr++ = (unsigned char) ((gdimage->red[pixel] * 77 + gdimage->green[pixel] * 151 + gdimage->blue[pixel] * 28 + 128) / 256); } while (y-- != y0); } while (x-- != x0); } return 0; }
void plD_state_png(PLStream *pls, PLINT op) { png_Dev *dev=(png_Dev *)pls->dev; PLFLT tmp_colour_pos; #if GD2_VERS >= 2 long temp_col; #endif switch (op) { #if GD2_VERS >= 2 case PLSTATE_WIDTH: gdImageSetThickness(dev->im_out, pls->width); break; #endif case PLSTATE_COLOR0: #if GD2_VERS >= 2 if ( (pls->icol0 == PL_RGB_COLOR)|| /* Should never happen since PL_RGB_COLOR is depreciated, but here for backwards compatibility */ (gdImageTrueColor(dev->im_out)) ) /* We will do this if we are in "TrueColour" mode */ { if ( (dev->totcol < NCOLOURS)|| /* See if there are slots left, if so we will allocate a new colour */ (gdImageTrueColor(dev->im_out)) ) /* In TrueColour mode we allocate each colour as we come to it */ { /* Next allocate a new colour to a temporary slot since what we do with it will varay depending on if its a pallter index or truecolour */ temp_col=gdImageColorAllocate(dev->im_out,pls->curcolor.r, pls->curcolor.g, pls->curcolor.b); if (gdImageTrueColor(dev->im_out)) dev->colour = temp_col; /* If it's truecolour, then we will directly set dev->colour to our "new" colour */ else { dev->colour = dev->totcol; /* or else, we will just set it to the last colour */ dev->totcol++; /* Bump the total colours for next time round */ } } } else /* just a normal colour allocate, so don't worry about the above stuff, just grab the index */ { dev->colour = pls->icol0; } #else dev->colour = pls->icol0; if (dev->colour == PL_RGB_COLOR) { if (dev->totcol < NCOLOURS) { gdImageColorAllocate(dev->im_out,pls->curcolor.r, pls->curcolor.g, pls->curcolor.b); dev->colour = dev->totcol; } } #endif break; case PLSTATE_COLOR1: #if GD2_VERS >= 2 if (!gdImageTrueColor(dev->im_out)) { #endif /* * Start by checking to see if we have to compensate for cases where * we don't have the full dynamic range of cmap1 at our disposal */ if (dev->ncol1<pls->ncol1) { tmp_colour_pos=dev->ncol1*((PLFLT)pls->icol1/(pls->ncol1>0 ? pls->ncol1 : 1)); dev->colour = pls->ncol0 + (int)tmp_colour_pos; } else dev->colour = pls->ncol0 + pls->icol1; #if GD2_VERS >= 2 } else /* it is a truecolour image */ { dev->colour = gdTrueColor(pls->curcolor.r, pls->curcolor.g, pls->curcolor.b); } #endif break; case PLSTATE_CMAP0: case PLSTATE_CMAP1: #if GD2_VERS >= 2 if ((dev->im_out != NULL) && !gdImageTrueColor(dev->im_out)) { #endif /* * Code to redefine the entire palette */ if (pls->color) setcmap(pls); #if GD2_VERS >= 2 } #endif break; } }