// C1 Code Set - Captioning Commands Control Codes int handle_708_C1 (cc708_service_decoder *decoder, unsigned char *data, int data_length) { struct S_COMMANDS_C1 com=COMMANDS_C1[data[0]-0x80]; if (com.length>data_length) { return -1; } switch (com.code) { case CW0: /* SetCurrentWindow */ case CW1: case CW2: case CW3: case CW4: case CW5: case CW6: case CW7: handle_708_CWx_SetCurrentWindow (decoder, com.code-CW0); /* Window 0 to 7 */ break; case CLW: handle_708_CLW_ClearWindows (decoder, data[1]); break; case DSW: handle_708_DSW_DisplayWindows (decoder, data[1]); break; case HDW: handle_708_HDW_HideWindows (decoder, data[1]); break; case TGW: handle_708_TGW_ToggleWindows (decoder, data[1]); break; case DLW: handle_708_DLW_DeleteWindows (decoder, data[1]); break; case DLY: handle_708_DLY_Delay (decoder, data[1]); break; case DLC: handle_708_DLC_DelayCancel (decoder); break; case RST: cc708_service_reset(decoder); break; case SPA: handle_708_SPA_SetPenAttributes (decoder, data); break; case SPC: handle_708_SPC_SetPenColor (decoder, data); break; case SPL: handle_708_SPL_SetPenLocation (decoder, data); break; case RSV93: case RSV94: case RSV95: case RSV96: break; case SWA: handle_708_SWA_SetWindowAttributes (decoder, data); break; case DF0: case DF1: case DF2: case DF3: case DF4: case DF5: case DF6: case DF7: handle_708_DFx_DefineWindow (decoder, com.code-DF0, data); /* Window 0 to 7 */ break; default: break; } return com.length; }
int handle_708_C1 (cc708_service_decoder *decoder, unsigned char *data, int data_length) { S_COMMANDS_C1 com=COMMANDS_C1[data[0]-0x80]; printf ("%s | C1: [%02X] [%s] [%s] (%d)\n", print_mstime(get_fts()), data[0],com.name,com.description, com.length); if (com.length>data_length) { printf ("C1: Warning: Not enough bytes for command.\n"); return -1; } switch (com.code) { case CW0: /* SetCurrentWindow */ case CW1: case CW2: case CW3: case CW4: case CW5: case CW6: case CW7: handle_708_CWx_SetCurrentWindow (decoder, com.code-CW0); /* Window 0 to 7 */ break; case CLW: handle_708_CLW_ClearWindows (decoder, data[1]); break; case DSW: handle_708_DSW_DisplayWindows (decoder, data[1]); break; case HDW: handle_708_HDW_HideWindows (decoder, data[1]); break; case TGW: handle_708_TGW_ToggleWindows (decoder, data[1]); break; case DLW: handle_708_DLW_DeleteWindows (decoder, data[1]); break; case DLY: handle_708_DLY_Delay (decoder, data[1]); break; case DLC: handle_708_DLC_DelayCancel (decoder); break; case RST: cc708_service_reset(decoder); break; case SPA: handle_708_SPA_SetPenAttributes (decoder, data); break; case SPC: handle_708_SPC_SetPenColor (decoder, data); break; case SPL: handle_708_SPL_SetPenLocation (decoder, data); break; case RSV93: case RSV94: case RSV95: case RSV96: printf ("Warning, found Reserved codes, ignored.\n"); break; case SWA: handle_708_SWA_SetWindowAttributes (decoder, data); break; case DF0: case DF1: case DF2: case DF3: case DF4: case DF5: case DF6: case DF7: handle_708_DFx_DefineWindow (decoder, com.code-DF0, data); /* Window 0 to 7 */ break; default: printf ("BUG: Unhandled code in handle_708_C1.\n"); break; } return com.length; }
void handle_708_DFx_DefineWindow (cc708_service_decoder *decoder, int window, unsigned char *data) { if (decoder->windows[window].is_defined && memcmp (decoder->windows[window].commands, data+1, 6)==0) { return; } decoder->windows[window].number=window; int priority = (data[1] ) & 0x7; int col_lock = (data[1]>>3) & 0x1; int row_lock = (data[1]>>4) & 0x1; int visible = (data[1]>>5) & 0x1; int anchor_vertical = data[2] & 0x7f; int relative_pos = (data[2]>>7); int anchor_horizontal = data[3]; int row_count = data[4] & 0xf; int anchor_point = data[4]>>4; int col_count = data[5] & 0x3f; int pen_style = data[6] & 0x7; int win_style = (data[6]>>3) & 0x7; col_count++; // These increments seems to be needed but no documentation row_count++; // backs it up if (anchor_vertical > I708_SCREENGRID_ROWS) anchor_vertical = I708_SCREENGRID_ROWS; decoder->windows[window].priority=priority; decoder->windows[window].col_lock=col_lock; decoder->windows[window].row_lock=row_lock; decoder->windows[window].visible=visible; decoder->windows[window].anchor_vertical=anchor_vertical; decoder->windows[window].relative_pos=relative_pos; decoder->windows[window].anchor_horizontal=anchor_horizontal; decoder->windows[window].row_count=row_count; decoder->windows[window].anchor_point=anchor_point; decoder->windows[window].col_count=col_count; decoder->windows[window].pen_style=pen_style; decoder->windows[window].win_style=win_style; if (!decoder->windows[window].is_defined) { // If the window is being created, all character positions in the window // are set to the fill color... //! @todo COLORS // ...and the pen location is set to (0,0) decoder->windows[window].pen_column=0; decoder->windows[window].pen_row=0; if (!decoder->windows[window].memory_reserved) { for (int i=0;i<=I708_MAX_ROWS;i++) { decoder->windows[window].rows[i]=(unsigned char *) malloc (I708_MAX_COLUMNS+1); if (decoder->windows[window].rows[i]==NULL) // Great { decoder->windows[window].is_defined=0; decoder->current_window=-1; for (int j=0;j<i;j++) free (decoder->windows[window].rows[j]); return; //! @todo Warn somehow } } decoder->windows[window].memory_reserved=1; } decoder->windows[window].is_defined=1; memset(&decoder->windows[window].attribs, 0, sizeof(e708Window_attribs)); clearWindowText (&decoder->windows[window]); } // ...also makes the defined windows the current window (setCurrentWindow) handle_708_CWx_SetCurrentWindow (decoder, window); memcpy (decoder->windows[window].commands, data+1, 6); }
void handle_708_DFx_DefineWindow (cc708_service_decoder *decoder, int window, unsigned char *data) { printf (" Entry in handle_708_DFx_DefineWindow, window [%d], attributes: \n", window); if (decoder->windows[window].is_defined && memcmp (decoder->windows[window].commands, data+1, 6)==0) { // When a decoder receives a DefineWindow command for an existing window, the // command is to be ignored if the command parameters are unchanged from the // previous window definition. printf (" Repeated window definition, ignored.\n"); return; } decoder->windows[window].number=window; int priority = (data[1] ) & 0x7; int col_lock = (data[1]>>3) & 0x1; int row_lock = (data[1]>>4) & 0x1; int visible = (data[1]>>5) & 0x1; int anchor_vertical = data[2] & 0x7f; int relative_pos = (data[2]>>7); int anchor_horizontal = data[3]; int row_count = data[4] & 0xf; int anchor_point = data[4]>>4; int col_count = data[5] & 0x3f; int pen_style = data[6] & 0x7; int win_style = (data[6]>>3) & 0x7; printf (" Priority: [%d] Column lock: [%3s] Row lock: [%3s]\n", priority, col_lock?"Yes": "No", row_lock?"Yes": "No"); printf (" Visible: [%3s] Anchor vertical: [%2d] Relative pos: [%s]\n", visible?"Yes": "No", anchor_vertical, relative_pos?"Yes": "No"); printf (" Anchor horizontal: [%3d] Row count: [%2d]+1 Anchor point: [%d]\n", anchor_horizontal, row_count, anchor_point); printf (" Column count: [%2d]1 Pen style: [%d] Win style: [%d]\n", col_count, pen_style, win_style); col_count++; // These increments seems to be needed but no documentation row_count++; // backs it up decoder->windows[window].priority=priority; decoder->windows[window].col_lock=col_lock; decoder->windows[window].row_lock=row_lock; decoder->windows[window].visible=visible; decoder->windows[window].anchor_vertical=anchor_vertical; decoder->windows[window].relative_pos=relative_pos; decoder->windows[window].anchor_horizontal=anchor_horizontal; decoder->windows[window].row_count=row_count; decoder->windows[window].anchor_point=anchor_point; decoder->windows[window].col_count=col_count; decoder->windows[window].pen_style=pen_style; decoder->windows[window].win_style=win_style; if (!decoder->windows[window].is_defined) { // If the window is being created, all character positions in the window // are set to the fill color... // TODO: COLORS // ...and the pen location is set to (0,0) decoder->windows[window].pen_column=0; decoder->windows[window].pen_row=0; if (!decoder->windows[window].memory_reserved) { for (int i=0;i<=I708_MAX_ROWS;i++) { decoder->windows[window].rows[i]=(unsigned char *) malloc (I708_MAX_COLUMNS+1); if (decoder->windows[window].rows[i]==NULL) // Great { decoder->windows[window].is_defined=0; decoder->current_window=-1; for (int j=0;j<i;j++) free (decoder->windows[window].rows[j]); return; // TODO: Warn somehow } } decoder->windows[window].memory_reserved=1; } decoder->windows[window].is_defined=1; clearWindowText (&decoder->windows[window]); } else { // Specs unclear here: Do we need to delete the text in the existing window? // We do this because one of the sample files demands it. // clearWindowText (&decoder->windows[window]); } // ...also makes the defined windows the current window (setCurrentWindow) handle_708_CWx_SetCurrentWindow (decoder, window); memcpy (decoder->windows[window].commands, data+1, 6); }