UVC host library
Dependents: LifeCam WebcamServer
uvc/myjpeg.cpp@3:3eb41d749f9a, 2012-08-15 (annotated)
- Committer:
- va009039
- Date:
- Wed Aug 15 13:52:53 2012 +0000
- Revision:
- 3:3eb41d749f9a
- Parent:
- 0:b0f04c137829
add USB_USE_MALLOC
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:b0f04c137829 | 1 | #include "mbed.h" |
va009039 | 0:b0f04c137829 | 2 | //#define __DEBUG |
va009039 | 0:b0f04c137829 | 3 | #include "mydbg.h" |
va009039 | 0:b0f04c137829 | 4 | #include "myjpeg.h" |
va009039 | 0:b0f04c137829 | 5 | |
va009039 | 0:b0f04c137829 | 6 | static const uint8_t dht[] = { |
va009039 | 0:b0f04c137829 | 7 | 0xFF,0xC4,0x01,0xA2,0x00,0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00, |
va009039 | 0:b0f04c137829 | 8 | 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, |
va009039 | 0:b0f04c137829 | 9 | 0x0B,0x01,0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00, |
va009039 | 0:b0f04c137829 | 10 | 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x10,0x00, |
va009039 | 0:b0f04c137829 | 11 | 0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,0x01, |
va009039 | 0:b0f04c137829 | 12 | 0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22, |
va009039 | 0:b0f04c137829 | 13 | 0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,0x24, |
va009039 | 0:b0f04c137829 | 14 | 0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,0x29, |
va009039 | 0:b0f04c137829 | 15 | 0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A, |
va009039 | 0:b0f04c137829 | 16 | 0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A, |
va009039 | 0:b0f04c137829 | 17 | 0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A, |
va009039 | 0:b0f04c137829 | 18 | 0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8, |
va009039 | 0:b0f04c137829 | 19 | 0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,0xC6, |
va009039 | 0:b0f04c137829 | 20 | 0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,0xE3, |
va009039 | 0:b0f04c137829 | 21 | 0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9, |
va009039 | 0:b0f04c137829 | 22 | 0xFA,0x11,0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01, |
va009039 | 0:b0f04c137829 | 23 | 0x02,0x77,0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07, |
va009039 | 0:b0f04c137829 | 24 | 0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33, |
va009039 | 0:b0f04c137829 | 25 | 0x52,0xF0,0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19, |
va009039 | 0:b0f04c137829 | 26 | 0x1A,0x26,0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46, |
va009039 | 0:b0f04c137829 | 27 | 0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66, |
va009039 | 0:b0f04c137829 | 28 | 0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85, |
va009039 | 0:b0f04c137829 | 29 | 0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3, |
va009039 | 0:b0f04c137829 | 30 | 0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA, |
va009039 | 0:b0f04c137829 | 31 | 0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8, |
va009039 | 0:b0f04c137829 | 32 | 0xD9,0xDA,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6, |
va009039 | 0:b0f04c137829 | 33 | 0xF7,0xF8,0xF9,0xFA, |
va009039 | 0:b0f04c137829 | 34 | }; |
va009039 | 0:b0f04c137829 | 35 | |
va009039 | 0:b0f04c137829 | 36 | myjpeg::myjpeg(uint8_t* buf, int len, int capacity) |
va009039 | 0:b0f04c137829 | 37 | { |
va009039 | 0:b0f04c137829 | 38 | DBG_ASSERT(buf); |
va009039 | 0:b0f04c137829 | 39 | DBG_ASSERT(len >= 0); |
va009039 | 0:b0f04c137829 | 40 | m_buf = buf; |
va009039 | 0:b0f04c137829 | 41 | m_len = len; |
va009039 | 0:b0f04c137829 | 42 | m_capacity = capacity; |
va009039 | 0:b0f04c137829 | 43 | } |
va009039 | 0:b0f04c137829 | 44 | |
va009039 | 0:b0f04c137829 | 45 | int myjpeg::getc() |
va009039 | 0:b0f04c137829 | 46 | { |
va009039 | 0:b0f04c137829 | 47 | if (m_pos >= m_len) { |
va009039 | 0:b0f04c137829 | 48 | return -1; |
va009039 | 0:b0f04c137829 | 49 | } |
va009039 | 0:b0f04c137829 | 50 | return m_buf[m_pos++]; |
va009039 | 0:b0f04c137829 | 51 | } |
va009039 | 0:b0f04c137829 | 52 | |
va009039 | 0:b0f04c137829 | 53 | int myjpeg::getBE16() |
va009039 | 0:b0f04c137829 | 54 | { |
va009039 | 0:b0f04c137829 | 55 | int c1 = getc(); |
va009039 | 0:b0f04c137829 | 56 | if (c1 == (-1)) { |
va009039 | 0:b0f04c137829 | 57 | return -1; |
va009039 | 0:b0f04c137829 | 58 | } |
va009039 | 0:b0f04c137829 | 59 | int c2 = getc(); |
va009039 | 0:b0f04c137829 | 60 | if (c2 == (-1)) { |
va009039 | 0:b0f04c137829 | 61 | return -1; |
va009039 | 0:b0f04c137829 | 62 | } |
va009039 | 0:b0f04c137829 | 63 | return c1<<8|c2; |
va009039 | 0:b0f04c137829 | 64 | } |
va009039 | 0:b0f04c137829 | 65 | |
va009039 | 0:b0f04c137829 | 66 | void myjpeg::analytics() |
va009039 | 0:b0f04c137829 | 67 | { |
va009039 | 0:b0f04c137829 | 68 | m_pos = 0; |
va009039 | 0:b0f04c137829 | 69 | SOS_pos = 0; |
va009039 | 0:b0f04c137829 | 70 | DHT_pos = 0; |
va009039 | 0:b0f04c137829 | 71 | int skip; |
va009039 | 0:b0f04c137829 | 72 | int lp; |
va009039 | 0:b0f04c137829 | 73 | while(1) { |
va009039 | 0:b0f04c137829 | 74 | int marker_pos = m_pos; |
va009039 | 0:b0f04c137829 | 75 | int c = getc(); |
va009039 | 0:b0f04c137829 | 76 | if (c == (-1)) { |
va009039 | 0:b0f04c137829 | 77 | break; |
va009039 | 0:b0f04c137829 | 78 | } |
va009039 | 0:b0f04c137829 | 79 | if (c != 0xff) { |
va009039 | 0:b0f04c137829 | 80 | continue; |
va009039 | 0:b0f04c137829 | 81 | } |
va009039 | 0:b0f04c137829 | 82 | c = getc(); |
va009039 | 0:b0f04c137829 | 83 | if (c == (-1)) { |
va009039 | 0:b0f04c137829 | 84 | break; |
va009039 | 0:b0f04c137829 | 85 | } |
va009039 | 0:b0f04c137829 | 86 | uint8_t marker = c; |
va009039 | 0:b0f04c137829 | 87 | switch(marker) { |
va009039 | 0:b0f04c137829 | 88 | case 0xd8: |
va009039 | 0:b0f04c137829 | 89 | DBG("%04X SOI\n", marker_pos); |
va009039 | 0:b0f04c137829 | 90 | skip = 0; |
va009039 | 0:b0f04c137829 | 91 | break; |
va009039 | 0:b0f04c137829 | 92 | case 0xd9: |
va009039 | 0:b0f04c137829 | 93 | DBG("%04X EOI\n", marker_pos); |
va009039 | 0:b0f04c137829 | 94 | skip = 0; |
va009039 | 0:b0f04c137829 | 95 | break; |
va009039 | 0:b0f04c137829 | 96 | case 0x00: |
va009039 | 0:b0f04c137829 | 97 | skip = 0; |
va009039 | 0:b0f04c137829 | 98 | break; |
va009039 | 0:b0f04c137829 | 99 | case 0xc0: |
va009039 | 0:b0f04c137829 | 100 | lp = getBE16(); |
va009039 | 0:b0f04c137829 | 101 | DBG("%04X SOF0 %d\n", marker_pos, lp); |
va009039 | 0:b0f04c137829 | 102 | skip = lp - 2; |
va009039 | 0:b0f04c137829 | 103 | break; |
va009039 | 0:b0f04c137829 | 104 | case 0xc4: |
va009039 | 0:b0f04c137829 | 105 | lp = getBE16(); |
va009039 | 0:b0f04c137829 | 106 | DBG("%04X DHT Lh: %d\n", marker_pos, lp); |
va009039 | 0:b0f04c137829 | 107 | //DBG("Tc: %d\n", buf[pos+2]>>4); |
va009039 | 0:b0f04c137829 | 108 | //DBG("Th: %d\n", buf[pos+2]&0xf); |
va009039 | 0:b0f04c137829 | 109 | DHT_pos = marker_pos; |
va009039 | 0:b0f04c137829 | 110 | skip = lp - 2; |
va009039 | 0:b0f04c137829 | 111 | break; |
va009039 | 0:b0f04c137829 | 112 | case 0xda: |
va009039 | 0:b0f04c137829 | 113 | lp = getBE16(); |
va009039 | 0:b0f04c137829 | 114 | DBG("%04X SOS Ls: %d\n", marker_pos, lp); |
va009039 | 0:b0f04c137829 | 115 | //DBG("Ns: %d\n", buf[pos+2]); |
va009039 | 0:b0f04c137829 | 116 | //for(i = 1; i <= buf[pos+2]; i++) { |
va009039 | 0:b0f04c137829 | 117 | // DBG("Cs%d: %d\n", i, buf[pos+3+(i-1)*2]); |
va009039 | 0:b0f04c137829 | 118 | // DBG("Td%d: %d\n", i, buf[pos+4+(i-1)*2]>>4); |
va009039 | 0:b0f04c137829 | 119 | // DBG("Ta%d: %d\n", i, buf[pos+4+(i-1)*2]&0xf); |
va009039 | 0:b0f04c137829 | 120 | //} |
va009039 | 0:b0f04c137829 | 121 | SOS_pos = marker_pos; |
va009039 | 0:b0f04c137829 | 122 | skip = lp - 2; |
va009039 | 0:b0f04c137829 | 123 | break; |
va009039 | 0:b0f04c137829 | 124 | case 0xdb: |
va009039 | 0:b0f04c137829 | 125 | lp = getBE16(); |
va009039 | 0:b0f04c137829 | 126 | DBG("%04X DQT %d\n", marker_pos, lp); |
va009039 | 0:b0f04c137829 | 127 | skip = lp - 2; |
va009039 | 0:b0f04c137829 | 128 | break; |
va009039 | 0:b0f04c137829 | 129 | case 0xe0: |
va009039 | 0:b0f04c137829 | 130 | lp = getBE16(); |
va009039 | 0:b0f04c137829 | 131 | DBG("%04X APP0 %d\n", marker_pos, lp); |
va009039 | 0:b0f04c137829 | 132 | skip = lp - 2; |
va009039 | 0:b0f04c137829 | 133 | break; |
va009039 | 0:b0f04c137829 | 134 | default: |
va009039 | 0:b0f04c137829 | 135 | DBG("%04X ??? %02X\n", marker_pos, marker); |
va009039 | 0:b0f04c137829 | 136 | skip = 0; |
va009039 | 0:b0f04c137829 | 137 | break; |
va009039 | 0:b0f04c137829 | 138 | } |
va009039 | 0:b0f04c137829 | 139 | while(skip-- > 0) { |
va009039 | 0:b0f04c137829 | 140 | getc(); |
va009039 | 0:b0f04c137829 | 141 | } |
va009039 | 0:b0f04c137829 | 142 | } |
va009039 | 0:b0f04c137829 | 143 | } |
va009039 | 0:b0f04c137829 | 144 | |
va009039 | 0:b0f04c137829 | 145 | int myjpeg::insertDHT() |
va009039 | 0:b0f04c137829 | 146 | { |
va009039 | 0:b0f04c137829 | 147 | DBG("m_len=%d m_capacity=%d SOS=%d\n", m_len, m_capacity, SOS_pos); |
va009039 | 0:b0f04c137829 | 148 | DBG_ASSERT(SOS_pos > 0); |
va009039 | 0:b0f04c137829 | 149 | DBG_ASSERT(SOS_pos < m_len); |
va009039 | 0:b0f04c137829 | 150 | DBG_ASSERT(m_len <= m_capacity); |
va009039 | 0:b0f04c137829 | 151 | DBG_ASSERT(sizeof(dht) == 420); |
va009039 | 0:b0f04c137829 | 152 | |
va009039 | 0:b0f04c137829 | 153 | int num1 = m_len - SOS_pos; |
va009039 | 0:b0f04c137829 | 154 | if (num1 > (m_capacity - SOS_pos - sizeof(dht))) { |
va009039 | 0:b0f04c137829 | 155 | num1 = m_capacity - SOS_pos - sizeof(dht); |
va009039 | 0:b0f04c137829 | 156 | } |
va009039 | 0:b0f04c137829 | 157 | DBG("num1=%d\n", num1); |
va009039 | 0:b0f04c137829 | 158 | DBG_ASSERT(SOS_pos+sizeof(dht)+num1 <= m_capacity); |
va009039 | 0:b0f04c137829 | 159 | memmove(m_buf+SOS_pos+sizeof(dht), m_buf+SOS_pos, num1); |
va009039 | 0:b0f04c137829 | 160 | |
va009039 | 0:b0f04c137829 | 161 | int num2 = sizeof(dht); |
va009039 | 0:b0f04c137829 | 162 | if (num2 > m_capacity - SOS_pos) { |
va009039 | 0:b0f04c137829 | 163 | num2 = m_capacity - SOS_pos; |
va009039 | 0:b0f04c137829 | 164 | } |
va009039 | 0:b0f04c137829 | 165 | DBG("num2=%d\n", num2); |
va009039 | 0:b0f04c137829 | 166 | DBG_ASSERT(SOS_pos+num2 <= m_capacity); |
va009039 | 0:b0f04c137829 | 167 | memcpy(m_buf+SOS_pos, dht, num2); |
va009039 | 0:b0f04c137829 | 168 | m_len += sizeof(dht); |
va009039 | 0:b0f04c137829 | 169 | if (m_len > m_capacity) { |
va009039 | 0:b0f04c137829 | 170 | m_len = m_capacity; |
va009039 | 0:b0f04c137829 | 171 | } |
va009039 | 0:b0f04c137829 | 172 | return m_len; |
va009039 | 0:b0f04c137829 | 173 | } |
va009039 | 0:b0f04c137829 | 174 | |
va009039 | 0:b0f04c137829 | 175 | int fgetBE16(FILE* fp) |
va009039 | 0:b0f04c137829 | 176 | { |
va009039 | 0:b0f04c137829 | 177 | int c1 = fgetc(fp); |
va009039 | 0:b0f04c137829 | 178 | if (c1 == EOF) { |
va009039 | 0:b0f04c137829 | 179 | return -1; |
va009039 | 0:b0f04c137829 | 180 | } |
va009039 | 0:b0f04c137829 | 181 | int c2 = fgetc(fp); |
va009039 | 0:b0f04c137829 | 182 | if (c2 == EOF) { |
va009039 | 0:b0f04c137829 | 183 | return -1; |
va009039 | 0:b0f04c137829 | 184 | } |
va009039 | 0:b0f04c137829 | 185 | return c1<<8|c2; |
va009039 | 0:b0f04c137829 | 186 | } |
va009039 | 0:b0f04c137829 | 187 | |
va009039 | 0:b0f04c137829 | 188 | void QcamCopy(const char* destination, const char* source) |
va009039 | 0:b0f04c137829 | 189 | { |
va009039 | 0:b0f04c137829 | 190 | FILE* fp; |
va009039 | 0:b0f04c137829 | 191 | FILE* fp2; |
va009039 | 0:b0f04c137829 | 192 | fp = fopen(source, "rb"); |
va009039 | 0:b0f04c137829 | 193 | if (fp == NULL) { |
va009039 | 0:b0f04c137829 | 194 | return; |
va009039 | 0:b0f04c137829 | 195 | } |
va009039 | 0:b0f04c137829 | 196 | fp2 = fopen(destination, "wb"); |
va009039 | 0:b0f04c137829 | 197 | if (fp2 == NULL) { |
va009039 | 0:b0f04c137829 | 198 | return; |
va009039 | 0:b0f04c137829 | 199 | } |
va009039 | 0:b0f04c137829 | 200 | int i,c1,c2; |
va009039 | 0:b0f04c137829 | 201 | bool f_dht = false; |
va009039 | 0:b0f04c137829 | 202 | bool f_lp = false; |
va009039 | 0:b0f04c137829 | 203 | while(!feof(fp)){ |
va009039 | 0:b0f04c137829 | 204 | c1 = fgetc(fp); |
va009039 | 0:b0f04c137829 | 205 | if (c1 != 0xff) { |
va009039 | 0:b0f04c137829 | 206 | fputc(c1, fp2); |
va009039 | 0:b0f04c137829 | 207 | continue; |
va009039 | 0:b0f04c137829 | 208 | } |
va009039 | 0:b0f04c137829 | 209 | c2 = fgetc(fp); |
va009039 | 0:b0f04c137829 | 210 | switch(c2) { |
va009039 | 0:b0f04c137829 | 211 | case 0xda: // SOS |
va009039 | 0:b0f04c137829 | 212 | if (!f_dht) { |
va009039 | 0:b0f04c137829 | 213 | for(i = 0; i < sizeof(dht); i++) { |
va009039 | 0:b0f04c137829 | 214 | fputc(dht[i], fp2); |
va009039 | 0:b0f04c137829 | 215 | } |
va009039 | 0:b0f04c137829 | 216 | f_dht = true; |
va009039 | 0:b0f04c137829 | 217 | } |
va009039 | 0:b0f04c137829 | 218 | f_lp = true; |
va009039 | 0:b0f04c137829 | 219 | break; |
va009039 | 0:b0f04c137829 | 220 | case 0xc4: // DHT |
va009039 | 0:b0f04c137829 | 221 | f_dht = true; |
va009039 | 0:b0f04c137829 | 222 | f_lp = true; |
va009039 | 0:b0f04c137829 | 223 | break; |
va009039 | 0:b0f04c137829 | 224 | case 0xc0: |
va009039 | 0:b0f04c137829 | 225 | case 0xdb: |
va009039 | 0:b0f04c137829 | 226 | case 0xe0: |
va009039 | 0:b0f04c137829 | 227 | f_lp = true; |
va009039 | 0:b0f04c137829 | 228 | break; |
va009039 | 0:b0f04c137829 | 229 | default: |
va009039 | 0:b0f04c137829 | 230 | f_lp = false; |
va009039 | 0:b0f04c137829 | 231 | break; |
va009039 | 0:b0f04c137829 | 232 | } |
va009039 | 0:b0f04c137829 | 233 | fputc(c1, fp2); |
va009039 | 0:b0f04c137829 | 234 | fputc(c2, fp2); // marker |
va009039 | 0:b0f04c137829 | 235 | if (f_lp) { |
va009039 | 0:b0f04c137829 | 236 | c1 = fgetc(fp); // length |
va009039 | 0:b0f04c137829 | 237 | c2 = fgetc(fp); |
va009039 | 0:b0f04c137829 | 238 | fputc(c1, fp2); |
va009039 | 0:b0f04c137829 | 239 | fputc(c2, fp2); |
va009039 | 0:b0f04c137829 | 240 | int skip = c1<<8|c2; |
va009039 | 0:b0f04c137829 | 241 | while(skip-- > 2) { |
va009039 | 0:b0f04c137829 | 242 | int c = fgetc(fp); |
va009039 | 0:b0f04c137829 | 243 | if (c == EOF) { |
va009039 | 0:b0f04c137829 | 244 | break; |
va009039 | 0:b0f04c137829 | 245 | } |
va009039 | 0:b0f04c137829 | 246 | fputc(c, fp2); |
va009039 | 0:b0f04c137829 | 247 | } |
va009039 | 0:b0f04c137829 | 248 | } |
va009039 | 0:b0f04c137829 | 249 | } |
va009039 | 0:b0f04c137829 | 250 | fclose(fp); |
va009039 | 0:b0f04c137829 | 251 | fclose(fp2); |
va009039 | 0:b0f04c137829 | 252 | } |