#include #include #include #include #include int height=8, width=50; int orient=DM_IMAGE_TOP_TO_BOTTOM, interleave=DM_IMAGE_INTERLACED_EVEN; int interlaced; int even; unsigned char *data; int *spatial_to_memory; int *temporal_to_memory; unsigned char *get_image_data(void) { data = malloc(2 * height * width); spatial_to_memory = malloc(sizeof(int) * height); temporal_to_memory = malloc(sizeof(int) * height); return data; } DMparams *get_image_params(void) { DMparams *p; dmParamsCreate(&p); dmSetImageDefaults(p, width, height, DM_IMAGE_PACKING_CbYCrY); dmParamsSetEnum(p, DM_IMAGE_ORIENTATION, orient); dmParamsSetEnum(p, DM_IMAGE_INTERLACING, interleave); return p; } int detect_whether_signal_is_interlaced(void) { return interlaced; } int detect_whether_frame_parity_is_even(void) { return even; } void error(char *msg) { printf("%s\n", msg); } int find_index_of(int item, int *array) /* assumes item is present */ { int i; for(i=0; i < height; i++) if (array[i] == item) return i; return -1; } void doit(void) { unsigned char *image = get_image_data(); /* the image data */ DMparams *imageparams = get_image_params(); /* MV/DM params for image */ int height = dmParamsGetInt(imageparams, DM_IMAGE_HEIGHT); int bytes_per_line = dmImageFrameSize(imageparams) / height; int i; /* our goal is to use DM_IMAGE_INTERLACING and DM_IMAGE_ORIENTATION * to compute the following four boolean variables: */ int signal_is_interlaced; /* signal: interlaced vs. progressive scan */ int even; /* signal: frame parity */ int full_frame; /* in-memory: frame layout */ int bottom_to_top; /* in-memory: orientation */ switch (dmParamsGetEnum(imageparams, DM_IMAGE_INTERLACING)) { case DM_IMAGE_INTERLACED_ODD: /* implies interlaced signal, odd parity, split-field */ signal_is_interlaced = 1; even = 0; full_frame = 0; break; case DM_IMAGE_INTERLACED_EVEN: /* implies interlaced signal, even parity, split-field */ signal_is_interlaced = 1; even = 1; full_frame = 0; break; case DM_IMAGE_NONINTERLACED: /* implies full-frame. * * DM_IMAGE_INTERLACING==DM_IMAGE_NONINTERLACED could refer * to either a progressive-scan or an interlaced signal. * we'll need that information in order to traverse all the * lines in temporal order. */ signal_is_interlaced = detect_whether_signal_is_interlaced(); if (signal_is_interlaced) { /* * DM_IMAGE_INTERLACING==DM_IMAGE_NONINTERLACED also doesn't * imply a frame parity. we'll need this in order to tell * which field is temporally first. */ even = detect_whether_frame_parity_is_even(); } full_frame = 1; break; default: error("unsupported DM_IMAGE_INTERLACING"); return; } if (!full_frame) /* split field: fields always same size */ assert(height % 2 == 0); switch (dmParamsGetEnum(imageparams, DM_IMAGE_ORIENTATION)) { case DM_IMAGE_TOP_TO_BOTTOM: /* * with top to bottom orientation, * - full frame images and each field of split-field images: * spatially lower (and thus temporally later) lines * are at higher memory addresses. * - split-field images: * the temporally later field is at a higher memory address. */ bottom_to_top = 0; break; case DM_IMAGE_BOTTOM_TO_TOP: /* * with bottom to top orientation, * - full frame images and each field of split-field images: * spatially higher (and thus temporally earlier) lines * are at higher memory addresses. * - split-field images: * the temporally earlier field is at a higher memory address. */ bottom_to_top = 1; break; default: error("unsupported DM_IMAGE_ORIENTATION"); return; } printf("
\n" "\n" "\n"); for(i=0; i < height; i++) /* traverse spatially from top to bottom */ { int line; /* first compute line assuming top-to-bottom orientation */ if (full_frame) /* full frame -- image already in spatial order! */ line = i; else /* split field representation */ { if ( even ^ ((i%2)==1) ) line = i/2; /* temporally first field */ else line = height/2 + i/2; /* temporally second field */ } if (bottom_to_top) /* adjust if bottom-to-top */ line = height - line - 1; /* access first byte of that line */ *(image + line*bytes_per_line) = 0xff; spatial_to_memory[i] = line; } for(i=0; i < height; i++) /* traverse temporally from earliest to latest */ { int line; /* first compute line assuming top-to-bottom orientation */ if (signal_is_interlaced) { if (full_frame) /* full frame */ { if ( even ^ (i >= height/2) ) line = 2*(i % (height/2)); /* temporally first field */ else line = 2*(i % (height/2)) + 1; /* temporally second field */ } else /* split fields -- image already in temporal order */ line = i; } else /* progressive scan -- image already in temporal order */ line = i; if (bottom_to_top) /* adjust if bottom-to-top */ line = height - line - 1; /* access first byte of that line */ *(image + line*bytes_per_line) = 0xff; temporal_to_memory[i] = line; } printf("\n" ""); { int q; printf("\n"); } printf("
Parameters:
    \n"); printf("
  • DM_IMAGE_ORIENTATION=="); switch (dmParamsGetEnum(imageparams, DM_IMAGE_ORIENTATION)) { case DM_IMAGE_TOP_TO_BOTTOM: printf("DM_IMAGE_TOP_TO_BOTTOM\n"); break; case DM_IMAGE_BOTTOM_TO_TOP: printf("DM_IMAGE_BOTTOM_TO_TOP\n"); break; } printf("
  • DM_IMAGE_INTERLACING=="); switch (dmParamsGetEnum(imageparams, DM_IMAGE_INTERLACING)) { case DM_IMAGE_INTERLACED_ODD: printf("DM_IMAGE_INTERLACED_ODD\n"); break; case DM_IMAGE_INTERLACED_EVEN: printf("DM_IMAGE_INTERLACED_EVEN\n"); break; case DM_IMAGE_NONINTERLACED: printf("DM_IMAGE_NONINTERLACED\n"); break; } if (full_frame) { printf("
  • signal is %s (not specified by params)\n", (signal_is_interlaced ? "interlaced" : "progressive scan")); if (signal_is_interlaced) printf("
  • frame parity is %s (not specified by params)\n", (even ? "even" : "odd")); } printf("
\n"); printf("Signal: %d-line %s signal", height, (signal_is_interlaced ? "interlaced" : "progressive scan")); if (signal_is_interlaced) printf(" (%s frame parity)", (even ? "even" : "odd")); printf("
\n"); printf("Memory: %s representation with %s orientation\n", (full_frame ? "full frame" : "split field"), (bottom_to_top ? "bottom-to-top" : "top-to-bottom")); printf("
In-Memory Order
" "(lowest to highest memory address)\n" "
Spatial Order
" "(highest to lowest vertical position)\n" "
Temporal Order
" "(earliest to latest data)\n" "
\n"); for(q=0; q < height; q++) { printf("Memory:%d Space:%d Time:%d
\n", q, find_index_of(q, spatial_to_memory), find_index_of(q, temporal_to_memory) ); } printf("
\n"); for(q=0; q < height; q++) { printf("Memory:%d Space:%d Time:%d
\n", spatial_to_memory[q], q, find_index_of(spatial_to_memory[q],temporal_to_memory) ); } printf("
\n"); for(q=0; q < height; q++) { printf("Memory:%d Space:%d Time:%d
\n", temporal_to_memory[q], find_index_of(temporal_to_memory[q], spatial_to_memory), q ); } printf("

\n

"); } int main( int argc, char **argv ) { int c; while ((c = getopt(argc, argv, "h:w:tbeon1:2:")) != EOF) { switch(c) { case 'h': height = atoi(optarg); break; case 'w': width = atoi(optarg); break; case 't': orient = DM_IMAGE_TOP_TO_BOTTOM; break; case 'b': orient = DM_IMAGE_BOTTOM_TO_TOP; break; case 'e': interleave = DM_IMAGE_INTERLACED_EVEN; break; case 'o': interleave = DM_IMAGE_INTERLACED_ODD; break; case 'n': interleave = DM_IMAGE_NONINTERLACED; break; case '1': interlaced = atoi(optarg); break; case '2': even = atoi(optarg); break; default: printf("huh?\n"); exit(2); } } doit(); return 0; }