diff options
Diffstat (limited to 'system/type/pdp_image.c')
-rw-r--r-- | system/type/pdp_image.c | 580 |
1 files changed, 0 insertions, 580 deletions
diff --git a/system/type/pdp_image.c b/system/type/pdp_image.c deleted file mode 100644 index 1aa9763..0000000 --- a/system/type/pdp_image.c +++ /dev/null @@ -1,580 +0,0 @@ -/* - * Pure Data Packet system implementation. : 16 bit image packet implementation - * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -/* - This file contains methods for the image packets - pdp_packet_new_* methods are several image packet constructors - pdp_type_* are image type checkers & converters - -*/ - -#include "pdp.h" -#include "pdp_internals.h" -#include <stdio.h> - - -/* the class object */ -static t_pdp_class* image_class; - - - -/* check dimensions */ -static void _checkdim(u32 width, u32 height){ - if ((pdp_imageproc_legalwidth(width) != width) || - (pdp_imageproc_legalheight(height) != height)){ - post("WARNING: request to create image packet with illegal dimensions %d x %d", width, height); - } -} - - -/* image packet constructors */ -int pdp_packet_new_image_YCrCb(u32 w, u32 h) -{ - t_pdp *header; - t_image *image; - int packet; - - - u32 size = w*h; - u32 totalnbpixels = size + (size >> 1); - u32 packet_size = totalnbpixels << 1; - - _checkdim(w,h); - - packet = pdp_packet_new(PDP_IMAGE, packet_size); - header = pdp_packet_header(packet); - image = pdp_packet_image_info(packet); - if (!header) return -1; - - image->encoding = PDP_IMAGE_YV12; - image->width = w; - image->height = h; - header->desc = pdp_packet_image_get_description(packet); - header->theclass = image_class; - - return packet; -} - -int pdp_packet_new_image_grey(u32 w, u32 h) -{ - t_pdp *header; - t_image *image; - int packet; - - - u32 size = w*h; - u32 totalnbpixels = size; - u32 packet_size = totalnbpixels << 1; - - _checkdim(w,h); - - packet = pdp_packet_new(PDP_IMAGE, packet_size); - header = pdp_packet_header(packet); - image = pdp_packet_image_info(packet); - if (!header) return -1; - - image->encoding = PDP_IMAGE_GREY; - image->width = w; - image->height = h; - header->desc = pdp_packet_image_get_description(packet); - header->theclass = image_class; - - return packet; -} - -int pdp_packet_new_image_mchp(u32 w, u32 h, u32 d) -{ - t_pdp *header; - t_image *image; - int packet; - - - u32 size = w*h*d; - u32 totalnbpixels = size; - u32 packet_size = totalnbpixels << 1; - - _checkdim(w,h); - - packet = pdp_packet_new(PDP_IMAGE, packet_size); - header = pdp_packet_header(packet); - image = pdp_packet_image_info(packet); - if (!header) return -1; - - - image->encoding = PDP_IMAGE_MCHP; - image->width = w; - image->height = h; - image->depth = d; - header->desc = pdp_packet_image_get_description(packet); - header->theclass = image_class; - - return packet; -} - - -int pdp_packet_new_image(u32 type, u32 w, u32 h) -{ - switch (type){ - case PDP_IMAGE_YV12: - return pdp_packet_new_image_YCrCb(w,h); - case PDP_IMAGE_GREY: - return pdp_packet_new_image_grey(w,h); - default: - return -1; - } -} - - -/****************** packet type checking and conversion methods ********************/ - - - -/* check if two image packets are allocated and of the same type */ -int pdp_packet_image_compat(int packet0, int packet1) -{ - t_pdp *header0 = pdp_packet_header(packet0); - t_pdp *header1 = pdp_packet_header(packet1); - t_image *image0 = pdp_packet_image_info(packet0); - t_image *image1 = pdp_packet_image_info(packet1); - - - if (!(pdp_packet_compat(packet0, packet1))) return 0; - if (header0->type != PDP_IMAGE){ - //post("pdp_type_compat_image: not a PDP_IMAGE"); - return 0; - } - if (image0->encoding != image1->encoding){ - //post("pdp_type_compat_image: encodings differ"); - return 0; - } - if (image0->width != image1->width){ - //post("pdp_type_compat_image: image withs differ"); - return 0; - } - if (image0->height != image1->height){ - //post("pdp_type_compat_image: image heights differ"); - return 0; - } - return 1; -} - -/* check if packet is a valid image packet */ -int pdp_packet_image_isvalid(int packet) -{ - t_pdp *header = pdp_packet_header(packet); - t_image *image = pdp_packet_image_info(packet); - if (!header) return 0; - if (PDP_IMAGE != header->type) return 0; - if ((PDP_IMAGE_YV12 != image->encoding) - && (PDP_IMAGE_GREY != image->encoding) - && (PDP_IMAGE_MCHP != image->encoding)) return 0; - - return 1; - -} - -/* set the channel mask for the image */ -void pdp_packet_image_set_chanmask(int packet, unsigned int chanmask) -{ - if (pdp_packet_image_isvalid(packet)) pdp_packet_image_info(packet)->chanmask = chanmask; - -} - - -t_image *pdp_packet_image_info(int packet) -{ - return (t_image *)pdp_packet_subheader(packet); -} - - -t_pdp_symbol *pdp_packet_image_get_description(int packet) -{ - t_pdp *header = pdp_packet_header(packet); - t_image *image = pdp_packet_image_info(packet); - char description[1024]; - char *c = description; - int encoding; - - if (!header) return pdp_gensym("invalid"); - else if (!header->desc){ - /* if description is not defined, try to reconstruct it (for backwards compat) */ - if (header->type == PDP_IMAGE){ - c += sprintf(c, "image"); - encoding = image->encoding; - switch(encoding){ - case PDP_IMAGE_YV12: c += sprintf(c, "/YCrCb"); break; - case PDP_IMAGE_GREY: c += sprintf(c, "/grey"); break; - case PDP_IMAGE_MCHP: c += sprintf(c, "/multi"); break; - default: - c += sprintf(c, "/unknown"); goto exit; - } - if (encoding == PDP_IMAGE_MCHP){ - c += sprintf(c, "/%dx%dx%d", - image->width, - image->height, - image->depth); - } - else { - c += sprintf(c, "/%dx%d", - image->width, - image->height); - } - - exit: - return pdp_gensym(description); - } - else return pdp_gensym("unknown"); - } - else return header->desc; -} - - - - - -/* IMAGE PACKAGE CONVERSION ROUTINES */ - -/* note: these are internal: no extra checking is done - it is assumed the packets are of correct type (the type template associated with the conversion program) */ - -// image/YCrCb/* -> image/grey/* -// image/multi/* -> image/grey/* (only first channel) -static int _pdp_packet_image_convert_YCrCb_to_grey(int packet, t_pdp_symbol *dest_template) -{ - t_pdp *header = pdp_packet_header(packet); - t_image *image = pdp_packet_image_info(packet); - int w = image->width; - int h = image->height; - int p = pdp_packet_new_image_grey(w,h); - if (p == -1) return p; - memcpy(pdp_packet_data(p), pdp_packet_data(packet), 2*w*h); - return p; -} - -// image/grey/* -> image/YCrCb/* -static int _pdp_packet_image_convert_grey_to_YCrCb(int packet, t_pdp_symbol *dest_template) -{ - t_pdp *header = pdp_packet_header(packet); - t_image *image = pdp_packet_image_info(packet); - int w = image->width; - int h = image->height; - int p = pdp_packet_new_image_YCrCb(w,h); - int y_bytes = 2*w*h; - void *data; - if (p == -1) return p; - data = pdp_packet_data(p); - memcpy(data, pdp_packet_data(packet), y_bytes); - memset(data+y_bytes, 0, y_bytes >> 1); - return p; -} - -// image/grey/* -> image/multi/* -static int _pdp_packet_image_convert_grey_to_multi(int packet, t_pdp_symbol *dest_template) -{ - t_pdp *header = pdp_packet_header(packet); - t_image *image = pdp_packet_image_info(packet); - int w = image->width; - int h = image->height; - int p = pdp_packet_new_image_mchp(w,h,1); - int y_bytes = 2*w*h; - void *data; - if (p == -1) return p; - data = pdp_packet_data(p); - memcpy(data, pdp_packet_data(packet), y_bytes); - return p; -} - -// image/multi/* -> image/YCrCb/* (only first 3 channels) -static int _pdp_packet_image_convert_multi_to_YCrCb(int packet, t_pdp_symbol *dest_template) -{ - t_pdp *header = pdp_packet_header(packet); - t_image *image = pdp_packet_image_info(packet); - s16 *data, *newdata; - - /* get info */ - int w = image->width; - int h = image->height; - int d = image->depth; - int plane_size = w*h; - - /* create new packet */ - int newpacket = pdp_packet_new_image_YCrCb(w, h); - if (-1 == newpacket) return -1; - - data = pdp_packet_data(packet); - newdata = pdp_packet_data(newpacket); - - /* copy channel 0 */ - memcpy(newdata, data, plane_size<<1); - newdata += plane_size; - data += plane_size; - - /* copy channel 1 */ - if (d >= 1) pdp_resample_halve(data, newdata, w, h); - else memset(newdata, 0, plane_size >> 1); - data += plane_size; - newdata += (plane_size >> 2); - - - /* copy channel 2 */ - if (d >= 2) pdp_resample_halve(data, newdata, w, h); - else memset(newdata, 0, plane_size >> 1); - - return newpacket; - -} - -// image/YCrCb/* -> image/multi/* -static int _pdp_packet_image_convert_YCrCb_to_multi(int packet, t_pdp_symbol *dest_template) -{ - t_pdp *header = pdp_packet_header(packet); - t_image *image = pdp_packet_image_info(packet); - s16 *data, *newdata; - - /* get info */ - int w = image->width; - int h = image->height; - int plane_size = w*h; - - /* create new packet */ - int newpacket = pdp_packet_new_image_mchp(w, h, 3); - if (-1 == newpacket) return -1; - - data = pdp_packet_data(packet); - newdata = pdp_packet_data(newpacket); - - /* copy channel 0 */ - memcpy(newdata, data, plane_size<<1); - newdata += plane_size; - data += plane_size; - w >>= 1; - h >>= 1; - - /* copy channel 1 */ - pdp_resample_double(data, newdata, w, h); - data += (plane_size >> 2); - newdata += plane_size; - - /* copy channel 2 */ - pdp_resample_double(data, newdata, w, h); - - return newpacket; - -} - -static void _pdp_description_get_dims(t_pdp_symbol *template, int *w, int *h, int *d) -{ - char *c = template->s_name; - // get requested dimensions - *w = 0; - *h = 0; - *d = 0; - while (*c++ != '/'); - while (*c++ != '/'); - sscanf(c, "%dx%dx%d", w, h, d); - -} - -// resample image/YCrCb/* -static int _pdp_packet_image_convert_resample_YCrCb(int packet, t_pdp_symbol *dest_template) -{ - int quality = 1; - int dst_w, dst_h, dummy; - int new_packet; - unsigned int src_size, src_voffset, src_uoffset; - unsigned int dst_size, dst_voffset, dst_uoffset; - t_pdp *header0 = pdp_packet_header(packet); - t_image *image0 = pdp_packet_image_info(packet); - unsigned int src_w = image0->width; - unsigned int src_h = image0->height; - short int *src_image = (short int *)pdp_packet_data(packet); - short int *dst_image; - _pdp_description_get_dims(dest_template, &dst_w, &dst_h, &dummy); - new_packet = pdp_packet_new_image_YCrCb(dst_w, dst_h); - if (-1 == new_packet) return -1; - dst_image = (short int*)pdp_packet_data(new_packet); - src_size = src_w*src_h; - src_voffset = src_size; - src_uoffset = src_size + (src_size>>2); - dst_size = dst_w*dst_h; - dst_voffset = dst_size; - dst_uoffset = dst_size + (dst_size>>2); - if (quality){ - pdp_resample_scale_bilin(src_image, dst_image, src_w, src_h, dst_w, dst_h); - pdp_resample_scale_bilin(src_image+src_voffset, dst_image+dst_voffset, src_w>>1, src_h>>1, dst_w>>1, dst_h>>1); - pdp_resample_scale_bilin(src_image+src_uoffset, dst_image+dst_uoffset, src_w>>1, src_h>>1, dst_w>>1, dst_h>>1); - } - else{ - pdp_resample_scale_nn(src_image, dst_image, src_w, src_h, dst_w, dst_h); - pdp_resample_scale_nn(src_image+src_voffset, dst_image+dst_voffset, src_w>>1, src_h>>1, dst_w>>1, dst_h>>1); - pdp_resample_scale_nn(src_image+src_uoffset, dst_image+dst_uoffset, src_w>>1, src_h>>1, dst_w>>1, dst_h>>1); - } - return new_packet; -} - -// resample image/grey/* and image/multi/* -static int _pdp_packet_image_convert_resample_multi(int packet, t_pdp_symbol *dest_template) -{ - int quality = 1; - int dst_w, dst_h, depth; - int new_packet; - unsigned int src_size; - unsigned int dst_size; - t_pdp *header0 = pdp_packet_header(packet); - t_image *image0 = pdp_packet_image_info(packet); - unsigned int src_w = image0->width; - unsigned int src_h = image0->height; - short int *src_image = (short int *)pdp_packet_data(packet); - short int *dst_image; - _pdp_description_get_dims(dest_template, &dst_w, &dst_h, &depth); - - if (depth == 0){ - depth = 1; - new_packet = pdp_packet_new_image_grey(dst_w, dst_h); - } - else { - new_packet = pdp_packet_new_image_mchp(dst_w, dst_h, depth); - } - if (-1 == new_packet) return -1; - - dst_image = (short int*)pdp_packet_data(new_packet); - - src_size = src_w*src_h; - dst_size = dst_w*dst_h; - while (depth--){ - if (quality){ - pdp_resample_scale_bilin(src_image, dst_image, src_w, src_h, dst_w, dst_h); - } - else{ - pdp_resample_scale_nn(src_image, dst_image, src_w, src_h, dst_w, dst_h); - } - src_image += src_size; - dst_image += dst_size; - } - - return new_packet; -} - -static int _pdp_packet_image_convert_fallback(int packet, t_pdp_symbol *dest_template) -{ - post("can't convert image type %s to %s", - pdp_packet_get_description(packet)->s_name, dest_template->s_name); - - return -1; -} - - - -/* the expensive factory method */ -static int pdp_image_factory(t_pdp_symbol *type) -{ - t_pdp_list *l; - t_pdp_symbol *s; - int t; - int w = 0; - int h = 0; - int d = 0; - int p = -1; - int n = 0; - int m = 0; - char *garbage = 0; - - //post("creating:"); - //post("%s", type->s_name); - - l = pdp_type_to_list(type); - s = pdp_list_pop(l).w_symbol; // first element is "image" - s = pdp_list_pop(l).w_symbol; - - /* get image type */ - if (s == pdp_gensym("grey")) t = PDP_IMAGE_GREY; - else if (s == pdp_gensym("YCrCb")) t = PDP_IMAGE_YV12; - else if (s == pdp_gensym("multi")) t = PDP_IMAGE_MCHP; - else goto exit; - - /* get image dimensions and create image */ - s = pdp_list_pop(l).w_symbol; - switch (t){ - case PDP_IMAGE_MCHP: - m = sscanf(s->s_name, "%dx%dx%d", &w, &h, &d); - p = pdp_packet_new_image_mchp(w,h,d); - break; - default: - sscanf(s->s_name, "%dx%d", &w, &h); - p = pdp_packet_new_image(t,w,h); - break; - } - if (p != -1){ - t_pdp *h = pdp_packet_header(p); - /* if type is not exact, delete the packet */ - if (type != h->desc) { - pdp_packet_delete(p); - p = -1; - } - } - exit: - pdp_list_free(l); - return p; -} - - - -void pdp_image_words_setup(t_pdp_class *c); - -void pdp_image_setup(void) -{ - t_pdp_conversion_program *program; - - /* setup the class object */ - image_class = pdp_class_new(pdp_gensym("image/*/*"), pdp_image_factory); - - /* setup image words */ - pdp_image_words_setup(image_class); - - - /* setup conversion programs */ - program = pdp_conversion_program_new(_pdp_packet_image_convert_YCrCb_to_grey, 0); - pdp_type_register_conversion(pdp_gensym("image/YCrCb/*"), pdp_gensym("image/grey/*"), program); - pdp_type_register_conversion(pdp_gensym("image/multi/*"), pdp_gensym("image/grey/*"), program); - - program = pdp_conversion_program_new(_pdp_packet_image_convert_grey_to_YCrCb, 0); - pdp_type_register_conversion(pdp_gensym("image/grey/*"), pdp_gensym("image/YCrCb/*"), program); - - program = pdp_conversion_program_new(_pdp_packet_image_convert_grey_to_multi, 0); - pdp_type_register_conversion(pdp_gensym("image/grey/*"), pdp_gensym("image/multi/*"), program); - - program = pdp_conversion_program_new(_pdp_packet_image_convert_multi_to_YCrCb, 0); - pdp_type_register_conversion(pdp_gensym("image/multi/*"), pdp_gensym("image/YCrCb/*"), program); - - program = pdp_conversion_program_new(_pdp_packet_image_convert_YCrCb_to_multi, 0); - pdp_type_register_conversion(pdp_gensym("image/YCrCb/*"), pdp_gensym("image/multi/*"), program); - - program = pdp_conversion_program_new(_pdp_packet_image_convert_resample_YCrCb, 0); - pdp_type_register_conversion(pdp_gensym("image/YCrCb/*"), pdp_gensym("image/YCrCb/*"), program); - - program = pdp_conversion_program_new(_pdp_packet_image_convert_resample_multi, 0); - pdp_type_register_conversion(pdp_gensym("image/multi/*"), pdp_gensym("image/multi/*"), program); - pdp_type_register_conversion(pdp_gensym("image/grey/*"), pdp_gensym("image/grey/*"), program); - - /* catch-all fallback */ - program = pdp_conversion_program_new(_pdp_packet_image_convert_fallback, 0); - pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("image/*/*"), program); - -} |