⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libmjpeg.c

📁 这个库实现了录象功能
💻 C
📖 第 1 页 / 共 3 页
字号:
  uint8_t * cpy_rows[3];  // Copy to buffer first  cpy_rows[0] = mjpeg->temp_rows[0][0];  cpy_rows[1] = mjpeg->temp_rows[1][0];  cpy_rows[2] = mjpeg->temp_rows[2][0];    lqt_rows_copy(row_pointers,                cpy_rows, mjpeg->output_w, mjpeg->output_h, mjpeg->coded_w, mjpeg->coded_w_uv,                mjpeg->rowspan, mjpeg->rowspan_uv, mjpeg->jpeg_color_model);    }void mjpeg_set_quality(mjpeg_t *mjpeg, int quality)  {  mjpeg->quality = quality;  }void mjpeg_set_float(mjpeg_t *mjpeg, int use_float)  {  mjpeg->use_float = use_float;  }void mjpeg_set_rowspan(mjpeg_t *mjpeg, int rowspan, int rowspan_uv)  {  mjpeg->rowspan = rowspan;  mjpeg->rowspan_uv = rowspan_uv;  }int mjpeg_get_fields(mjpeg_t *mjpeg)  {  return mjpeg->fields;  }mjpeg_t* mjpeg_new(int w,                    int h,                    int fields)  {  mjpeg_t *result = calloc(1, sizeof(*result));    result->output_w = w;  result->output_h = h;  result->fields = fields;  result->quality = 80;  result->use_float = 0;    // Calculate coded dimensions  result->coded_w = (w % 16) ? w + (16 - (w % 16)) : w;  result->coded_w_uv = result->coded_w / 2;    result->coded_h = (h % 16) ? h + (16 - (h % 16)) : h;    return result;  }void mjpeg_delete(mjpeg_t *mjpeg)  {  if(mjpeg->compressor) mjpeg_delete_compressor(mjpeg->compressor);  if(mjpeg->decompressor) mjpeg_delete_decompressor(mjpeg->decompressor);  delete_temps(mjpeg);  delete_buffer(&mjpeg->output_data, &mjpeg->output_size, &mjpeg->output_allocated);  free(mjpeg);  }/* Open up a space to insert a marker */static void insert_space(unsigned char **buffer,                          long *buffer_size,                          long *buffer_allocated,                         long space_start,                         long space_len)  {  int in, out;  // Make sure enough space is available  if(*buffer_allocated - *buffer_size < space_len)    {    *buffer_allocated += space_len;    *buffer = realloc(*buffer, *buffer_allocated);    }  // Shift data back  for(in = *buffer_size - 1, out = *buffer_size - 1 + space_len;      in >= space_start;      in--, out--)    {    (*buffer)[out] = (*buffer)[in];    }  *buffer_size += space_len;  }static inline int nextbyte(unsigned char *data, long *offset, long length)  {  if(length - *offset < 1) return 0;  *offset += 1;  return (unsigned char)data[*offset - 1];  }static inline int next_int32(unsigned char *data, long *offset, long length)  {  if(length - *offset < 4)    {    *offset = length;    return 0;    }  *offset += 4;  return ((((unsigned int)data[*offset - 4]) << 24) |           (((unsigned int)data[*offset - 3]) << 16) |           (((unsigned int)data[*offset - 2]) << 8) |           (((unsigned int)data[*offset - 1])));  }static inline int read_int16(unsigned char *data, long *offset, long length)  {  if(length - *offset < 2)	    {    *offset = length;    return 0;    }  *offset += 2;  return ((((unsigned int)data[*offset - 2]) << 8) |           (((unsigned int)data[*offset - 1])));  }static inline intnext_int16(unsigned char *data, long *offset, long length)  {  if(length - *offset < 2)	    {    return 0;    }  return ((((unsigned int)data[*offset]) << 8) |           (((unsigned int)data[*offset + 1])));  }static inline voidwrite_int32(unsigned char *data, long *offset, long length,            unsigned int value)  {  if(length - *offset < 4)    {    *offset = length;    return;    }  data[(*offset)++] = (unsigned int)(value & 0xff000000) >> 24;  data[(*offset)++] = (unsigned int)(value & 0xff0000) >> 16;  data[(*offset)++] = (unsigned int)(value & 0xff00) >> 8;  data[(*offset)++] = (unsigned char)(value & 0xff);  return;  }static int next_marker(unsigned char *buffer, long *offset, long buffer_size)  {  while(*offset < buffer_size - 1)    {    if(buffer[*offset] == 0xff && buffer[*offset + 1] != 0xff)      {      (*offset) += 2;      return buffer[*offset - 1];      }		    (*offset)++;    }  return 0;  }/* Find the next marker after offset and return 0 on success */static int find_marker(unsigned char *buffer,                        long *offset,                        long buffer_size,                       unsigned long marker_type)  {  long result = 0;  while(!result && *offset < buffer_size)    {    int marker = next_marker(buffer, offset, buffer_size);    if(marker == (marker_type & 0xff)) result = 1;    }  return !result;  }typedef struct  {  int field_size;  int padded_field_size;  int next_offset;  int quant_offset;  int huffman_offset;  int image_offset;  int scan_offset;  int data_offset;  } mjpeg_qt_hdr;#if 0#define LML_MARKER_SIZE 0x2c#define LML_MARKER_TAG 0xffe3static void insert_lml33_markers(unsigned char **buffer,                           long *field2_offset,                           long *buffer_size,                           long *buffer_allocated)  {  long marker_offset = -1;  /* Search for existing marker to replace */  //	marker_offset = find_marker(*buffer, *buffer_size, LML_MARKER_TAG);  /* Insert new marker */  if(marker_offset < 0)    {    marker_offset = 2;    insert_space(buffer,                  buffer_size,                  buffer_allocated,                 2,                 LML_MARKER_SIZE);    }  }#endifstatic void table_offsets(unsigned char *buffer,                           long buffer_size,                           mjpeg_qt_hdr *header)  {  int done = 0;  long offset = 0;  int marker = 0;  int field = 0;  int len;  bzero(header, sizeof(mjpeg_qt_hdr) * 2);  // Read every marker to get the offsets for the headers  for(field = 0; field < 2; field++)    {    done = 0;    while(!done)      {      marker = next_marker(buffer,                            &offset,                            buffer_size);      len = 0;      switch(marker)        {        case M_SOI:          // The first field may be padded          if(field > 0)             {            header[0].next_offset =               header[0].padded_field_size =               offset - 2;            }          len = 0;          break;        case M_DQT:          if(!header[field].quant_offset)            {            header[field].quant_offset = offset - 2;            if(field > 0)              header[field].quant_offset -= header[0].next_offset;            }          len = read_int16(buffer, &offset, buffer_size);          len -= 2;          break;        case M_DHT:          if(!header[field].huffman_offset)            {            header[field].huffman_offset = offset - 2;            if(field > 0)              header[field].huffman_offset -= header[0].next_offset;            }          len = read_int16(buffer, &offset, buffer_size);          len -= 2;          break;        case M_SOF0:          if(!header[field].image_offset)            {            header[field].image_offset = offset - 2;            if(field > 0)              header[field].image_offset -= header[0].next_offset;            }          len = read_int16(buffer, &offset, buffer_size);          len -= 2;          break;        case M_SOS:          header[field].scan_offset = offset - 2;          if(field > 0)            header[field].scan_offset -= header[0].next_offset;          len = read_int16(buffer, &offset, buffer_size);          len -= 2;          header[field].data_offset = offset + len;          if(field > 0)            header[field].data_offset -= header[0].next_offset;          break;          //				case 0:        case M_EOI:          if(field > 0)             {            header[field].field_size =               header[field].padded_field_size =               offset - header[0].next_offset;            header[field].next_offset = 0;            }          else            {            // Often misses second SOI but gets first EOI            //						header[0].next_offset =             //							header[0].padded_field_size =             //							offset;            }          done = 1;          len = 0;          break;        default:          // Junk appears between fields          len = 0;          //					len = read_int16(buffer, &offset, buffer_size);          //					len -= 2;          break;        }      if(!done) offset += len;      }    }  }static void insert_quicktime_marker(unsigned char *buffer,                                     long buffer_size,                                     long offset,                                     mjpeg_qt_hdr *header)  {  write_int32(buffer, &offset, buffer_size, 0xff000000 |               ((unsigned long)M_APP1 << 16) |               (QUICKTIME_MARKER_SIZE - 2));  write_int32(buffer, &offset, buffer_size, 0);  write_int32(buffer, &offset, buffer_size, QUICKTIME_JPEG_TAG);  write_int32(buffer, &offset, buffer_size, header->field_size);  write_int32(buffer, &offset, buffer_size, header->padded_field_size);  write_int32(buffer, &offset, buffer_size, header->next_offset);  write_int32(buffer, &offset, buffer_size, header->quant_offset);  write_int32(buffer, &offset, buffer_size, header->huffman_offset);  write_int32(buffer, &offset, buffer_size, header->image_offset);  write_int32(buffer, &offset, buffer_size, header->scan_offset);  write_int32(buffer, &offset, buffer_size, header->data_offset);  }void mjpeg_insert_quicktime_markers(unsigned char **buffer,                                     long *buffer_size,                                     long *buffer_allocated,                                    int fields,                                    long *field2_offset)  {  mjpeg_qt_hdr header[2];  if(fields < 2) return;  // Get offsets for tables in both fields  table_offsets(*buffer, *buffer_size, header);  header[0].field_size += QUICKTIME_MARKER_SIZE;  header[0].padded_field_size += QUICKTIME_MARKER_SIZE;  header[0].next_offset += QUICKTIME_MARKER_SIZE;  header[0].quant_offset += QUICKTIME_MARKER_SIZE;  header[0].huffman_offset += QUICKTIME_MARKER_SIZE;  header[0].image_offset += QUICKTIME_MARKER_SIZE;  header[0].scan_offset += QUICKTIME_MARKER_SIZE;  header[0].data_offset += QUICKTIME_MARKER_SIZE;  header[1].field_size += QUICKTIME_MARKER_SIZE;  header[1].padded_field_size += QUICKTIME_MARKER_SIZE;  header[1].quant_offset += QUICKTIME_MARKER_SIZE;  header[1].huffman_offset += QUICKTIME_MARKER_SIZE;  header[1].image_offset += QUICKTIME_MARKER_SIZE;  header[1].scan_offset += QUICKTIME_MARKER_SIZE;  header[1].data_offset += QUICKTIME_MARKER_SIZE;  *field2_offset = header[0].next_offset;  // Insert APP1 marker  insert_space(buffer,                buffer_size,                buffer_allocated,               2,               QUICKTIME_MARKER_SIZE);  insert_quicktime_marker(*buffer,                           *buffer_size,                           2,                           &header[0]);  insert_space(buffer,                buffer_size,                buffer_allocated,               header[0].next_offset + 2,               QUICKTIME_MARKER_SIZE);  header[1].next_offset = 0;  insert_quicktime_marker(*buffer,                           *buffer_size,                           header[0].next_offset + 2,                           &header[1]);  }static void read_quicktime_markers(unsigned char *buffer,                                    long buffer_size,                                    mjpeg_qt_hdr *header)  {  long offset = 0;  int marker_count = 0;  int result = 0;  while(marker_count < 2 && offset < buffer_size && !result)    {    result = find_marker(buffer,                          &offset,                          buffer_size,                         M_APP1);    if(!result)      {      // Marker size      read_int16(buffer, &offset, buffer_size);      // Zero      next_int32(buffer, &offset, buffer_size);      // MJPA      next_int32(buffer, &offset, buffer_size);      // Information      header[marker_count].field_size = next_int32(buffer, &offset, buffer_size);      header[marker_count].padded_field_size = next_int32(buffer, &offset, buffer_size);      header[marker_count].next_offset = next_int32(buffer, &offset, buffer_size);      header[marker_count].quant_offset = next_int32(buffer, &offset, buffer_size);      header[marker_count].huffman_offset = next_int32(buffer, &offset, buffer_size);      header[marker_count].image_offset = next_int32(buffer, &offset, buffer_size);      header[marker_count].scan_offset = next_int32(buffer, &offset, buffer_size);      header[marker_count].data_offset = next_int32(buffer, &offset, buffer_size);      marker_count++;      }    }  }long mjpeg_get_quicktime_field2(unsigned char *buffer, long buffer_size)  {  mjpeg_qt_hdr header[2];  bzero(&header, sizeof(mjpeg_qt_hdr) * 2);  read_quicktime_markers(buffer, buffer_size, header);  return header[0].next_offset;  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -