#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include /** * cog_frame_new: * * Creates a new CogFrame object. The created frame is uninitialized * and has no data storage associated with it. The caller must fill * in the required information. * * Returns: a new CogFrame object */ CogFrame * cog_frame_new (void) { CogFrame *frame; frame = cog_malloc0 (sizeof (*frame)); frame->refcount = 1; return frame; } /** * cog_frame_new_and_alloc: * * Creates a new CogFrame object with the requested size and format. * * Returns: a new CogFrame object */ CogFrame * cog_frame_new_and_alloc (CogMemoryDomain * domain, CogFrameFormat format, int width, int height) { return cog_frame_new_and_alloc_extended (domain, format, width, height, 0); } CogFrame * cog_frame_new_and_alloc_extended (CogMemoryDomain * domain, CogFrameFormat format, int width, int height, int extension) { CogFrame *frame = cog_frame_new (); int bytes_pp; int h_shift, v_shift; int chroma_width; int chroma_height; int ext_width; int ext_height; COG_ASSERT (width > 0); COG_ASSERT (height > 0); frame->format = format; frame->width = width; frame->height = height; frame->domain = domain; frame->extension = extension; ext_width = width + extension * 2; ext_height = height + extension * 2; if (COG_FRAME_IS_PACKED (format)) { COG_ASSERT (extension == 0); frame->components[0].format = format; frame->components[0].width = width; frame->components[0].height = height; if (format == COG_FRAME_FORMAT_AYUV) { frame->components[0].stride = width * 4; } else { frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 2; } frame->components[0].length = frame->components[0].stride * height; if (domain) { //frame->regions[0] = cog_memory_domain_alloc (domain, // frame->components[0].length); } else { frame->regions[0] = cog_malloc (frame->components[0].length); } frame->components[0].data = frame->regions[0]; frame->components[0].v_shift = 0; frame->components[0].h_shift = 0; return frame; } switch (COG_FRAME_FORMAT_DEPTH (format)) { case COG_FRAME_FORMAT_DEPTH_U8: bytes_pp = 1; break; case COG_FRAME_FORMAT_DEPTH_S16: bytes_pp = 2; break; case COG_FRAME_FORMAT_DEPTH_S32: bytes_pp = 4; break; default: COG_ASSERT (0); bytes_pp = 0; break; } h_shift = COG_FRAME_FORMAT_H_SHIFT (format); v_shift = COG_FRAME_FORMAT_V_SHIFT (format); chroma_width = ROUND_UP_SHIFT (width, h_shift); chroma_height = ROUND_UP_SHIFT (height, v_shift); frame->components[0].format = format; frame->components[0].width = width; frame->components[0].height = height; frame->components[0].stride = ROUND_UP_4 ((width + extension * 2) * bytes_pp); frame->components[0].length = frame->components[0].stride * (frame->components[0].height + extension * 2); frame->components[0].v_shift = 0; frame->components[0].h_shift = 0; frame->components[1].format = format; frame->components[1].width = chroma_width; frame->components[1].height = chroma_height; frame->components[1].stride = ROUND_UP_4 ((chroma_width + extension * 2) * bytes_pp); frame->components[1].length = frame->components[1].stride * (frame->components[1].height + extension * 2); frame->components[1].v_shift = v_shift; frame->components[1].h_shift = h_shift; frame->components[2].format = format; frame->components[2].width = chroma_width; frame->components[2].height = chroma_height; frame->components[2].stride = ROUND_UP_4 ((chroma_width + extension * 2) * bytes_pp); frame->components[2].length = frame->components[2].stride * (frame->components[2].height + extension * 2); frame->components[2].v_shift = v_shift; frame->components[2].h_shift = h_shift; if (domain) { //frame->regions[0] = cog_memory_domain_alloc (domain, // frame->components[0].length + // frame->components[1].length + frame->components[2].length); } else { frame->regions[0] = malloc (frame->components[0].length + frame->components[1].length + frame->components[2].length); } frame->components[0].data = frame->regions[0] + frame->components[0].stride * extension + bytes_pp * extension; frame->components[1].data = frame->regions[0] + frame->components[0].length + frame->components[1].stride * extension + bytes_pp * extension; frame->components[2].data = frame->regions[0] + frame->components[0].length + frame->components[1].length + frame->components[2].stride * extension + bytes_pp * extension; return frame; } /** * cog_frame_new_from_data_YUY2: * * Creates a new CogFrame object with the requested size using * the data pointed to by @data. The data must be in YUY2 format. * The data must remain for the lifetime of the CogFrame object. * It is recommended to use cog_frame_set_free_callback() for * notification when the data is no longer needed. * * Returns: a new CogFrame object */ CogFrame * cog_frame_new_from_data_YUY2 (void *data, int width, int height) { CogFrame *frame = cog_frame_new (); frame->format = COG_FRAME_FORMAT_YUYV; frame->width = width; frame->height = height; frame->components[0].format = frame->format; frame->components[0].width = width; frame->components[0].height = height; frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 2; frame->components[0].data = data; frame->components[0].length = frame->components[0].stride * height; frame->components[0].v_shift = 0; frame->components[0].h_shift = 0; return frame; } /** * cog_frame_new_from_data_YUY2: * * Creates a new CogFrame object with the requested size using * the data pointed to by @data. The data must be in UYVY format. * The data must remain for the lifetime of the CogFrame object. * It is recommended to use cog_frame_set_free_callback() for * notification when the data is no longer needed. * * Returns: a new CogFrame object */ CogFrame * cog_frame_new_from_data_UYVY (void *data, int width, int height) { CogFrame *frame = cog_frame_new (); frame->format = COG_FRAME_FORMAT_UYVY; frame->width = width; frame->height = height; frame->components[0].format = frame->format; frame->components[0].width = width; frame->components[0].height = height; frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 2; frame->components[0].data = data; frame->components[0].length = frame->components[0].stride * height; frame->components[0].v_shift = 0; frame->components[0].h_shift = 0; return frame; } /** * cog_frame_new_from_data_YUY2: * * Creates a new CogFrame object with the requested size using * the data pointed to by @data. The data must be in UYVY format, * although the row stride is allowed to be different than what * would normally be calculated from @width. * The data must remain for the lifetime of the CogFrame object. * It is recommended to use cog_frame_set_free_callback() for * notification when the data is no longer needed. * * Returns: a new CogFrame object */ CogFrame * cog_frame_new_from_data_UYVY_full (void *data, int width, int height, int stride) { CogFrame *frame = cog_frame_new (); frame->format = COG_FRAME_FORMAT_UYVY; frame->width = width; frame->height = height; frame->components[0].width = width; frame->components[0].height = height; frame->components[0].stride = stride; frame->components[0].data = data; frame->components[0].length = frame->components[0].stride * height; frame->components[0].v_shift = 0; frame->components[0].h_shift = 0; return frame; } /** * cog_frame_new_from_data_AYUV: * * Creates a new CogFrame object with the requested size using * the data pointed to by @data. The data must be in AYUV format. * The data must remain for the lifetime of the CogFrame object. * It is recommended to use cog_frame_set_free_callback() for * notification when the data is no longer needed. * * Returns: a new CogFrame object */ CogFrame * cog_frame_new_from_data_AYUV (void *data, int width, int height) { CogFrame *frame = cog_frame_new (); frame->format = COG_FRAME_FORMAT_AYUV; frame->width = width; frame->height = height; frame->components[0].format = frame->format; frame->components[0].width = width; frame->components[0].height = height; frame->components[0].stride = width * 4; frame->components[0].data = data; frame->components[0].length = frame->components[0].stride * height; frame->components[0].v_shift = 0; frame->components[0].h_shift = 0; return frame; } /** * cog_frame_new_from_data_v216: * * Creates a new CogFrame object with the requested size using * the data pointed to by @data. The data must be in v216 format. * The data must remain for the lifetime of the CogFrame object. * It is recommended to use cog_frame_set_free_callback() for * notification when the data is no longer needed. * * Returns: a new CogFrame object */ CogFrame * cog_frame_new_from_data_v216 (void *data, int width, int height) { CogFrame *frame = cog_frame_new (); frame->format = COG_FRAME_FORMAT_v216; frame->width = width; frame->height = height; frame->components[0].format = frame->format; frame->components[0].width = width; frame->components[0].height = height; frame->components[0].stride = ROUND_UP_POW2 (width, 1) * 4; frame->components[0].data = data; frame->components[0].length = frame->components[0].stride * height; frame->components[0].v_shift = 0; frame->components[0].h_shift = 0; return frame; } /** * cog_frame_new_from_data_v210: * * Creates a new CogFrame object with the requested size using * the data pointed to by @data. The data must be in v210 format. * The data must remain for the lifetime of the CogFrame object. * It is recommended to use cog_frame_set_free_callback() for * notification when the data is no longer needed. * * Returns: a new CogFrame object */ CogFrame * cog_frame_new_from_data_v210 (void *data, int width, int height) { CogFrame *frame = cog_frame_new (); frame->format = COG_FRAME_FORMAT_v210; frame->width = width; frame->height = height; frame->components[0].format = frame->format; frame->components[0].width = width; frame->components[0].height = height; frame->components[0].stride = ((width + 47) / 48) * 128; frame->components[0].data = data; frame->components[0].length = frame->components[0].stride * height; frame->components[0].v_shift = 0; frame->components[0].h_shift = 0; return frame; } /** * cog_frame_new_from_data_I420: * * Creates a new CogFrame object with the requested size using * the data pointed to by @data. The data must be in I420 format. * The data must remain for the lifetime of the CogFrame object. * It is recommended to use cog_frame_set_free_callback() for * notification when the data is no longer needed. * * Returns: a new CogFrame object */ CogFrame * cog_frame_new_from_data_I420 (void *data, int width, int height) { CogFrame *frame = cog_frame_new (); frame->format = COG_FRAME_FORMAT_U8_420; frame->width = width; frame->height = height; frame->components[0].format = frame->format; frame->components[0].width = width; frame->components[0].height = height; frame->components[0].stride = ROUND_UP_POW2 (width, 2); frame->components[0].data = data; frame->components[0].length = frame->components[0].stride * ROUND_UP_POW2 (frame->components[0].height, 1); frame->components[0].v_shift = 0; frame->components[0].h_shift = 0; frame->components[1].format = frame->format; frame->components[1].width = ROUND_UP_SHIFT (width, 1); frame->components[1].height = ROUND_UP_SHIFT (height, 1); frame->components[1].stride = ROUND_UP_POW2 (frame->components[1].width, 2); frame->components[1].length = frame->components[1].stride * frame->components[1].height; frame->components[1].data = frame->components[0].data + frame->components[0].length; frame->components[1].v_shift = 1; frame->components[1].h_shift = 1; frame->components[2].format = frame->format; frame->components[2].width = ROUND_UP_SHIFT (width, 1); frame->components[2].height = ROUND_UP_SHIFT (height, 1); frame->components[2].stride = ROUND_UP_POW2 (frame->components[2].width, 2); frame->components[2].length = frame->components[2].stride * frame->components[2].height; frame->components[2].data = frame->components[1].data + frame->components[1].length; frame->components[2].v_shift = 1; frame->components[2].h_shift = 1; return frame; } /** * cog_frame_new_from_data_YV12: * * Creates a new CogFrame object with the requested size using * the data pointed to by @data. The data must be in YV12 format. * The data must remain for the lifetime of the CogFrame object. * It is recommended to use cog_frame_set_free_callback() for * notification when the data is no longer needed. * * Returns: a new CogFrame object */ CogFrame * cog_frame_new_from_data_YV12 (void *data, int width, int height) { CogFrame *frame = cog_frame_new (); frame->format = COG_FRAME_FORMAT_U8_420; frame->width = width; frame->height = height; frame->components[0].format = frame->format; frame->components[0].width = width; frame->components[0].height = height; frame->components[0].stride = ROUND_UP_POW2 (width, 2); frame->components[0].data = data; frame->components[0].length = frame->components[0].stride * ROUND_UP_POW2 (frame->components[0].height, 1); frame->components[0].v_shift = 0; frame->components[0].h_shift = 0; frame->components[2].format = frame->format; frame->components[2].width = ROUND_UP_SHIFT (width, 1); frame->components[2].height = ROUND_UP_SHIFT (height, 1); frame->components[2].stride = ROUND_UP_POW2 (frame->components[2].width, 2); frame->components[2].length = frame->components[2].stride * frame->components[2].height; frame->components[2].data = frame->components[0].data + frame->components[0].length; frame->components[2].v_shift = 1; frame->components[2].h_shift = 1; frame->components[1].format = frame->format; frame->components[1].width = ROUND_UP_SHIFT (width, 1); frame->components[1].height = ROUND_UP_SHIFT (height, 1); frame->components[1].stride = ROUND_UP_POW2 (frame->components[1].width, 2); frame->components[1].length = frame->components[1].stride * frame->components[1].height; frame->components[1].data = frame->components[2].data + frame->components[2].length; frame->components[1].v_shift = 1; frame->components[1].h_shift = 1; return frame; } /** * cog_frame_new_from_data_Y42B: * * Creates a new CogFrame object with the requested size using * the data pointed to by @data. The data must be in Y42B format. * The data must remain for the lifetime of the CogFrame object. * It is recommended to use cog_frame_set_free_callback() for * notification when the data is no longer needed. * * Returns: a new CogFrame object */ CogFrame * cog_frame_new_from_data_Y42B (void *data, int width, int height) { CogFrame *frame = cog_frame_new (); frame->format = COG_FRAME_FORMAT_U8_422; frame->width = width; frame->height = height; frame->components[0].format = frame->format; frame->components[0].width = width; frame->components[0].height = height; frame->components[0].stride = ROUND_UP_POW2 (width, 2); frame->components[0].data = data; frame->components[0].length = frame->components[0].stride * ROUND_UP_POW2 (frame->components[0].height, 1); frame->components[0].v_shift = 0; frame->components[0].h_shift = 0; frame->components[1].format = frame->format; frame->components[1].width = ROUND_UP_SHIFT (width, 1); frame->components[1].height = height; frame->components[1].stride = ROUND_UP_POW2 (frame->components[1].width, 2); frame->components[1].length = frame->components[1].stride * frame->components[1].height; frame->components[1].data = frame->components[0].data + frame->components[0].length; frame->components[1].v_shift = 0; frame->components[1].h_shift = 1; frame->components[2].format = frame->format; frame->components[2].width = ROUND_UP_SHIFT (width, 1); frame->components[2].height = height; frame->components[2].stride = ROUND_UP_POW2 (frame->components[2].width, 2); frame->components[2].length = frame->components[2].stride * frame->components[2].height; frame->components[2].data = frame->components[1].data + frame->components[1].length; frame->components[2].v_shift = 0; frame->components[2].h_shift = 1; return frame; } /** * cog_frame_new_from_data_Y444: * * Creates a new CogFrame object with the requested size using * the data pointed to by @data. The data must be in Y444 format. * The data must remain for the lifetime of the CogFrame object. * It is recommended to use cog_frame_set_free_callback() for * notification when the data is no longer needed. * * Returns: a new CogFrame object */ CogFrame * cog_frame_new_from_data_Y444 (void *data, int width, int height) { CogFrame *frame = cog_frame_new (); frame->format = COG_FRAME_FORMAT_U8_444; frame->width = width; frame->height = height; frame->components[0].format = frame->format; frame->components[0].width = width; frame->components[0].height = height; frame->components[0].stride = ROUND_UP_POW2 (width, 4); frame->components[0].data = data; frame->components[0].length = frame->components[0].stride * ROUND_UP_POW2 (frame->components[0].height, 1); frame->components[0].v_shift = 0; frame->components[0].h_shift = 0; frame->components[1].format = frame->format; frame->components[1].width = width; frame->components[1].height = height; frame->components[1].stride = ROUND_UP_POW2 (width, 4); frame->components[1].length = frame->components[1].stride * frame->components[1].height; frame->components[1].data = frame->components[0].data + frame->components[0].length; frame->components[1].v_shift = 0; frame->components[1].h_shift = 0; frame->components[2].format = frame->format; frame->components[2].width = width; frame->components[2].height = height; frame->components[2].stride = ROUND_UP_POW2 (width, 4); frame->components[2].length = frame->components[2].stride * frame->components[2].height; frame->components[2].data = frame->components[1].data + frame->components[1].length; frame->components[2].v_shift = 0; frame->components[2].h_shift = 0; return frame; } /** * cog_frame_new_from_data_RGB: * * Creates a new CogFrame object with the requested size using * the data pointed to by @data. The data must be in RGB format. * The data must remain for the lifetime of the CogFrame object. * It is recommended to use cog_frame_set_free_callback() for * notification when the data is no longer needed. * * Returns: a new CogFrame object */ CogFrame * cog_frame_new_from_data_RGB (void *data, int width, int height) { CogFrame *frame = cog_frame_new (); frame->format = COG_FRAME_FORMAT_RGB; frame->width = width; frame->height = height; frame->components[0].width = width; frame->components[0].height = height; frame->components[0].stride = ROUND_UP_4 (width * 3); frame->components[0].data = data; frame->components[0].length = frame->components[0].stride * height; frame->components[0].v_shift = 0; frame->components[0].h_shift = 0; return frame; } static CogFrame * cog_frame_new_from_data_RGB32 (void *data, int width, int height, int format) { CogFrame *frame = cog_frame_new (); frame->format = format; frame->width = width; frame->height = height; frame->components[0].width = width; frame->components[0].height = height; frame->components[0].stride = width * 4; frame->components[0].data = data; frame->components[0].length = frame->components[0].stride * height; frame->components[0].v_shift = 0; frame->components[0].h_shift = 0; return frame; } CogFrame * cog_frame_new_from_data_RGBx (void *data, int width, int height) { return cog_frame_new_from_data_RGB32 (data, width, height, COG_FRAME_FORMAT_RGBx); } CogFrame * cog_frame_new_from_data_xRGB (void *data, int width, int height) { return cog_frame_new_from_data_RGB32 (data, width, height, COG_FRAME_FORMAT_xRGB); } CogFrame * cog_frame_new_from_data_BGRx (void *data, int width, int height) { return cog_frame_new_from_data_RGB32 (data, width, height, COG_FRAME_FORMAT_BGRx); } CogFrame * cog_frame_new_from_data_xBGR (void *data, int width, int height) { return cog_frame_new_from_data_RGB32 (data, width, height, COG_FRAME_FORMAT_xBGR); } CogFrame * cog_frame_new_from_data_RGBA (void *data, int width, int height) { return cog_frame_new_from_data_RGB32 (data, width, height, COG_FRAME_FORMAT_RGBA); } CogFrame * cog_frame_new_from_data_ARGB (void *data, int width, int height) { return cog_frame_new_from_data_RGB32 (data, width, height, COG_FRAME_FORMAT_ARGB); } CogFrame * cog_frame_new_from_data_BGRA (void *data, int width, int height) { return cog_frame_new_from_data_RGB32 (data, width, height, COG_FRAME_FORMAT_BGRA); } CogFrame * cog_frame_new_from_data_ABGR (void *data, int width, int height) { return cog_frame_new_from_data_RGB32 (data, width, height, COG_FRAME_FORMAT_ABGR); } /** * cog_frame_dup: * * Creates a new CogFrame object with the same dimensions and format * as @frame, and copies the data from the @frame to the new object. * * Returns: a new CogFrame object */ CogFrame * cog_frame_dup (CogFrame * frame) { return cog_frame_dup_extended (frame, 0); } CogFrame * cog_frame_dup_extended (CogFrame * frame, int extension) { CogFrame *dup_frame; dup_frame = cog_frame_new_and_alloc_extended (frame->domain, frame->format, frame->width, frame->height, extension); cog_frame_convert (dup_frame, frame); return dup_frame; } /** * cog_frame_clone: * * Creates a new CogFrame object with the same dimensions and format * as @frame. This function leaves the data in the new object * uninitialized. * * Returns: a new CogFrame object */ CogFrame * cog_frame_clone (CogMemoryDomain * domain, CogFrame * frame) { return cog_frame_new_and_alloc (domain, frame->format, frame->width, frame->height); } /** * cog_frame_ref: * @frame: a frame object * * Increases the reference count of @frame. * * Returns: the value of @frame */ CogFrame * cog_frame_ref (CogFrame * frame) { frame->refcount++; return frame; } /** * cog_frame_unref: * @frame: a frame object * * Decreases the reference count of @frame. If the new reference * count is 0, the frame is freed. If a frame free callback was * set, this function is called. * * Returns: the value of @frame */ void cog_frame_unref (CogFrame * frame) { int i; COG_ASSERT (frame->refcount > 0); frame->refcount--; if (frame->refcount == 0) { if (frame->free) { frame->free (frame, frame->priv); } #ifdef HAVE_OPENGL if (COG_FRAME_IS_OPENGL (frame)) { cog_opengl_frame_cleanup (frame); } #endif for (i = 0; i < 3; i++) { if (frame->regions[i]) { if (frame->domain) { //cog_memory_domain_memfree(frame->domain, frame->regions[i]); } else { free (frame->regions[i]); } } } if (frame->virt_frame1) { cog_frame_unref (frame->virt_frame1); } if (frame->virt_frame2) { cog_frame_unref (frame->virt_frame2); } if (frame->virt_priv) { cog_free (frame->virt_priv); } cog_free (frame); } } /** * cog_frame_set_free_callback: * @frame: a frame object * @free_func: the function to call when the frame is freed * @priv: callback key * * Sets a function that will be called when the object reference * count drops to zero and the object is freed. */ void cog_frame_set_free_callback (CogFrame * frame, CogFrameFreeFunc free_func, void *priv) { frame->free = free_func; frame->priv = priv; } /** * cog_frame_convert: * @dest: destination frame * @src: source frame * * Copies data from the source frame to the destination frame, converting * formats if necessary. Only a few conversions are supported. */ void cog_frame_convert (CogFrame * dest, CogFrame * src) { CogFrame *frame; CogFrameFormat dest_format; COG_ASSERT (dest != NULL); COG_ASSERT (src != NULL); switch (dest->format) { case COG_FRAME_FORMAT_YUYV: case COG_FRAME_FORMAT_UYVY: dest_format = COG_FRAME_FORMAT_U8_422; break; case COG_FRAME_FORMAT_AYUV: case COG_FRAME_FORMAT_ARGB: dest_format = COG_FRAME_FORMAT_U8_444; break; default: dest_format = dest->format; break; } cog_frame_ref (src); frame = cog_virt_frame_new_unpack (src); COG_DEBUG ("unpack %p", frame); if (COG_FRAME_FORMAT_DEPTH (dest_format) != COG_FRAME_FORMAT_DEPTH (frame->format)) { if (COG_FRAME_FORMAT_DEPTH (dest_format) == COG_FRAME_FORMAT_DEPTH_U8) { frame = cog_virt_frame_new_convert_u8 (frame); COG_DEBUG ("convert_u8 %p", frame); } else if (COG_FRAME_FORMAT_DEPTH (dest_format) == COG_FRAME_FORMAT_DEPTH_S16) { frame = cog_virt_frame_new_convert_s16 (frame); COG_DEBUG ("convert_s16 %p", frame); } } if ((dest_format & 3) != (frame->format & 3)) { frame = cog_virt_frame_new_subsample (frame, dest_format); COG_DEBUG ("subsample %p", frame); } switch (dest->format) { case COG_FRAME_FORMAT_YUYV: frame = cog_virt_frame_new_pack_YUY2 (frame); COG_DEBUG ("pack_YUY2 %p", frame); break; case COG_FRAME_FORMAT_UYVY: frame = cog_virt_frame_new_pack_UYVY (frame); COG_DEBUG ("pack_UYVY %p", frame); break; case COG_FRAME_FORMAT_AYUV: frame = cog_virt_frame_new_pack_AYUV (frame); COG_DEBUG ("pack_AYUV %p", frame); break; default: break; } if (dest->width < frame->width || dest->height < frame->height) { COG_DEBUG ("crop %d %d to %d %d", frame->width, frame->height, dest->width, dest->height); frame = cog_virt_frame_new_crop (frame, dest->width, dest->height); COG_DEBUG ("crop %p", frame); } if (dest->width > src->width || dest->height > src->height) { frame = cog_virt_frame_new_edgeextend (frame, dest->width, dest->height); COG_DEBUG ("edgeextend %p", frame); } cog_virt_frame_render (frame, dest); cog_frame_unref (frame); } #if 0 void cog_frame_md5 (CogFrame * frame, uint32_t * state) { uint8_t *line; int x, y, k; state[0] = 0x67452301; state[1] = 0xefcdab89; state[2] = 0x98badcfe; state[3] = 0x10325476; x = 0; y = 0; k = 0; for (k = 0; k < 3; k++) { for (y = 0; y < frame->components[k].height; y++) { line = COG_FRAME_DATA_GET_LINE (&frame->components[k], y); for (x = 0; x + 63 < frame->components[k].width; x += 64) { oil_md5 (state, (uint32_t *) (line + x)); } if (x < frame->components[k].width) { uint8_t tmp[64]; int left; left = frame->components[k].width - x; memcpy (tmp, line + x, left); memset (tmp + left, 0, 64 - left); oil_md5 (state, (uint32_t *) tmp); } } } COG_DEBUG ("md5 %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", state[0] & 0xff, (state[0] >> 8) & 0xff, (state[0] >> 16) & 0xff, (state[0] >> 24) & 0xff, state[1] & 0xff, (state[1] >> 8) & 0xff, (state[1] >> 16) & 0xff, (state[1] >> 24) & 0xff, state[2] & 0xff, (state[2] >> 8) & 0xff, (state[2] >> 16) & 0xff, (state[2] >> 24) & 0xff, state[3] & 0xff, (state[3] >> 8) & 0xff, (state[3] >> 16) & 0xff, (state[3] >> 24) & 0xff); } #endif void cog_frame_split_fields (CogFrame * dest1, CogFrame * dest2, CogFrame * src) { CogFrame src_tmp; COG_ASSERT ((src->height & 1) == 0); memcpy (&src_tmp, src, sizeof (src_tmp)); src_tmp.height = src->height / 2; src_tmp.components[0].stride *= 2; src_tmp.components[1].stride *= 2; src_tmp.components[2].stride *= 2; cog_frame_convert (dest1, &src_tmp); src_tmp.components[0].data = COG_FRAME_DATA_GET_LINE (&src->components[0], 1); src_tmp.components[1].data = COG_FRAME_DATA_GET_LINE (&src->components[1], 1); src_tmp.components[2].data = COG_FRAME_DATA_GET_LINE (&src->components[2], 1); cog_frame_convert (dest2, &src_tmp); } void cog_frame_get_subdata (CogFrame * frame, CogFrameData * fd, int component, int x, int y) { CogFrameData *comp = frame->components + component; COG_ASSERT (COG_FRAME_FORMAT_DEPTH (comp->format) == COG_FRAME_FORMAT_DEPTH_U8); fd->format = comp->format; fd->data = COG_FRAME_DATA_GET_PIXEL_U8 (comp, x, y); fd->stride = comp->stride; fd->width = MAX (0, comp->width - x); fd->height = MAX (0, comp->height - y); fd->h_shift = comp->h_shift; fd->v_shift = comp->v_shift; }