示例#1
0
static void path_sendraw(struct net_seq_stream *net, char *url,
		char *hdr, char *data, int dlen)
{
	int i;
	struct nrf_raw_msg msg;

	chprintf((BaseSequentialStream *)net,
			"HTTP/1.1 200 OK\r\nContent-type: text/plain\r\n\r\n");

	if (dlen != PAYLOADSZ * 2)
		goto out;

	for (i = 0; i < PAYLOADSZ; i++) {
		if (!nibble_valid(data[i * 2]) ||
		    !nibble_valid(data[i * 2 + 1]))
			goto out;
		msg.data[i] = (get_nibble(data[i * 2]) << 4) |
			get_nibble(data[i * 2 + 1]);
	}

	nrf_send(&msg);

	chprintf((BaseSequentialStream *)net,
			"OK\r\n");
	return;

out:
	chprintf((BaseSequentialStream *)net,
			"ERR\r\n");
}
示例#2
0
文件: med3_load.c 项目: GCrean/libxmp
static uint16 get_nibbles(uint8 *mem,uint16 *nbnum,uint8 nbs)
{
	uint16 res = 0;

	while (nbs--) {
		res <<= 4;
		res |= get_nibble(mem,nbnum);
	}

	return res;
}
示例#3
0
文件: med3_load.c 项目: GCrean/libxmp
static int unpack_block(struct module_data *m, uint16 bnum, uint8 *from)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event;
	uint32 linemsk0 = *((uint32 *)from), linemsk1 = *((uint32 *)from + 1);
	uint32 fxmsk0 = *((uint32 *)from + 2), fxmsk1 = *((uint32 *)from + 3);
	uint32 *lmptr = &linemsk0, *fxptr = &fxmsk0;
	uint16 fromn = 0, lmsk;
	uint8 *fromst = from + 16, bcnt, *tmpto;
	uint8 *patbuf, *to;
	int i, j, trkn = mod->chn;

	from += 16;
	patbuf = to = calloc(3, 4 * 64);
	if (to == NULL)
		return -1;

	for (i = 0; i < 64; i++) {
		if (i == 32) {
			lmptr = &linemsk1;
			fxptr = &fxmsk1;
		}

		if (*lmptr & MASK) {
			lmsk = get_nibbles(fromst, &fromn, (uint8)(trkn / 4));
			lmsk <<= (16 - trkn);
			tmpto = to;

			for (bcnt = 0; bcnt < trkn; bcnt++) {
				if (lmsk & 0x8000) {
					*tmpto = (uint8)get_nibbles(fromst,
						&fromn,2);
					*(tmpto + 1) = (get_nibble(fromst,
							&fromn) << 4);
				}
				lmsk <<= 1;
				tmpto += 3;
			}
		}

		if (*fxptr & MASK) {
			lmsk = get_nibbles(fromst,&fromn,(uint8)(trkn / 4));
			lmsk <<= (16 - trkn);
			tmpto = to;

			for (bcnt = 0; bcnt < trkn; bcnt++) {
				if (lmsk & 0x8000) {
					*(tmpto+1) |= get_nibble(fromst,
							&fromn);
					*(tmpto+2) = (uint8)get_nibbles(fromst,
							&fromn,2);
				}
				lmsk <<= 1;
				tmpto += 3;
			}
		}
		to += 3 * trkn;
		*lmptr <<= 1;
		*fxptr <<= 1;
	}

	for (i = 0; i < 64; i++) {
		for (j = 0; j < 4; j++) {
			event = &EVENT(bnum, j, i);

			event->note = patbuf[i * 12 + j * 3 + 0];
			if (event->note)
				event->note += 48;
			event->ins  = patbuf[i * 12 + j * 3 + 1] >> 4;
			if (event->ins)
				event->ins++;
			event->fxt  = patbuf[i * 12 + j * 3 + 1] & 0x0f;
			event->fxp  = patbuf[i * 12 + j * 3 + 2];

			switch (event->fxt) {
			case 0x00:	/* arpeggio */
			case 0x01:	/* slide up */
			case 0x02:	/* slide down */
			case 0x03:	/* portamento */
			case 0x04:	/* vibrato? */
				break;
			case 0x0c:	/* set volume (BCD) */
				event->fxp = MSN(event->fxp) * 10 +
							LSN(event->fxp);
				break;
			case 0x0d:	/* volume slides */
				event->fxt = FX_VOLSLIDE;
				break;
			case 0x0f:	/* tempo/break */
				if (event->fxp == 0)
					event->fxt = FX_BREAK;
				if (event->fxp == 0xff) {
					event->fxp = event->fxt = 0;
					event->vol = 1;
				} else if (event->fxp == 0xfe) {
					event->fxp = event->fxt = 0;
				} else if (event->fxp == 0xf1) {
					event->fxt = FX_EXTENDED;
					event->fxp = (EX_RETRIG << 4) | 3;
				} else if (event->fxp == 0xf2) {
					event->fxt = FX_EXTENDED;
					event->fxp = (EX_CUT << 4) | 3;
				} else if (event->fxp == 0xf3) {
					event->fxt = FX_EXTENDED;
					event->fxp = (EX_DELAY << 4) | 3;
				} else if (event->fxp > 10) {
					event->fxt = FX_S3M_BPM;
					event->fxp = 125 * event->fxp / 33;
				}
				break;
			default:
				event->fxp = event->fxt = 0;
			}
		}
	}

	free(patbuf);

	return 0;
}
/* This is largely from spudec, ffmpeg */
int decompress_subtitle(mpeg3_t *file, mpeg3_subtitle_t *subtitle)
{
    int i, j, pass;
    unsigned char *ptr = subtitle->data;
    unsigned char *end = subtitle->data + subtitle->size;
    int even_offset = 0;
    int odd_offset = 0;

    /* packet size */
    ptr += 2;

    /* data packet size */
    if(ptr + 2 > end) return 1;

    int data_size = (*ptr++) << 8;
    data_size |= *ptr++;

    unsigned char *data_start = ptr;
    /*
     * printf("decompress_subtitle %d 0x%02x%02x size=%d data_size=%d\n",
     * __LINE__,
     * subtitle->data[0],
     * subtitle->data[1],
     * subtitle->size,
     * data_size);
     */

//	if(ptr + data_size - 2 > end) return 1;

    /* Advance to control sequences */
    ptr += data_size - 2;

    subtitle->palette[0] = 0x00;
    subtitle->palette[1] = 0x01;
    subtitle->palette[2] = 0x02;
    subtitle->palette[3] = 0x03;

    subtitle->alpha[0] = 0xff;
    subtitle->alpha[1] = 0xff;
    subtitle->alpha[2] = 0xff;
    subtitle->alpha[3] = 0xff;

    subtitle->x1 = 0;
    subtitle->x2 = 720;
    subtitle->y1 = 2;
    subtitle->y2 = 575;
    subtitle->w = 720;
    subtitle->h = 575;
    subtitle->start_time = 1897;
    subtitle->stop_time = 175;

    /* Control sequence */
    unsigned char *control_start = 0;
    unsigned char *next_control_start = ptr;
    int got_alpha = 0;
    while(ptr < end && control_start != next_control_start)
    {
        control_start = next_control_start;

        /* Date */
        if(ptr + 2 > end) break;
        int date = (*ptr++) << 8;
        date |= *ptr++;

        /* Offset of next control sequence */
        if(ptr + 2 > end) break;
        int next = (*ptr++) << 8;
        next |= *ptr++;

        next_control_start = subtitle->data + next;

        int done = 0;
        while(ptr < end && !done)
        {
            int type = *ptr++;

            switch(type)
            {
            case 0x00:
                subtitle->force = 1;
                break;

            case 0x01:
                subtitle->start_time = date;
//printf("decompress_subtitle %d\n", subtitle->start_time);
                break;

            case 0x02:
                subtitle->stop_time = date;
                break;

            case 0x03:
                /* Entry in palette of each color */
                if(ptr + 2 > end) return 1;
//printf("decompress_subtitle %d\n", __LINE__);
                subtitle->palette[0] = (*ptr) >> 4;
                subtitle->palette[1] = (*ptr++) & 0xf;
                subtitle->palette[2] = (*ptr) >> 4;
                subtitle->palette[3] = (*ptr++) & 0xf;
//printf("subtitle palette %d %d %d %d\n", subtitle->palette[0], subtitle->palette[1], subtitle->palette[2], subtitle->palette[3]);
                break;

            case 0x04:
                /* Alpha corresponding to each color */
                if(ptr + 2 > end) return 1;
//printf("decompress_subtitle %d\n", __LINE__);
                subtitle->alpha[3] = ((*ptr) >> 4) * 255 / 15;
                subtitle->alpha[2] = ((*ptr++) & 0xf) * 255 / 15;
                subtitle->alpha[1] = ((*ptr) >> 4) * 255 / 15;
                subtitle->alpha[0] = ((*ptr++) & 0xf) * 255 / 15;
                got_alpha = 1;
//printf("subtitle alphas %d %d %d %d\n", subtitle->alpha[0], subtitle->alpha[1], subtitle->alpha[2], subtitle->alpha[3]);
#ifdef OVERRIDE_ALPHA
                subtitle->alpha[3] = 0xff;
                subtitle->alpha[2] = 0x80;
                subtitle->alpha[1] = 0x40;
                subtitle->alpha[0] = 0x00;
#endif
                break;

            case 0x05:
                /* Extent of image on screen */
                if(ptr + 6 > end) return 1;
//printf("decompress_subtitle %d\n", __LINE__);
                /*
                 * printf("decompress_subtitle 10 %02x %02x %02x %02x %02x %02x\n",
                 * ptr[0],
                 * ptr[1],
                 * ptr[2],
                 * ptr[3],
                 * ptr[4],
                 * ptr[5]);
                 */
                subtitle->x1 = (*ptr++) << 4;
                subtitle->x1 |= (*ptr) >> 4;
                subtitle->x2 = ((*ptr++) & 0xf) << 8;
                subtitle->x2 |= *ptr++;
                subtitle->y1 = (*ptr++) << 4;
                subtitle->y1 |= (*ptr) >> 4;
                subtitle->y2 = ((*ptr++) & 0xf) << 8;
                subtitle->y2 |= *ptr++;
                subtitle->x2++;
                subtitle->y2++;
                subtitle->w = subtitle->x2 - subtitle->x1;
                subtitle->h = subtitle->y2 - subtitle->y1 + 2;
                /*
                 * printf("decompress_subtitle 20 x1=%d x2=%d y1=%d y2=%d\n",
                 * subtitle->x1,
                 * subtitle->x2,
                 * subtitle->y1,
                 * subtitle->y2);
                 */
                CLAMP(subtitle->w, 1, 2048);
                CLAMP(subtitle->h, 1, 2048);
                CLAMP(subtitle->x1, 0, 2048);
                CLAMP(subtitle->x2, 0, 2048);
                CLAMP(subtitle->y1, 0, 2048);
                CLAMP(subtitle->y2, 0, 2048);
                break;

            case 0x06:
                /* offsets of even and odd field in compressed data */
                if(ptr + 4 > end) return 1;
//printf("decompress_subtitle %d\n", __LINE__);
                even_offset = (ptr[0] << 8) | (ptr[1]);
                odd_offset = (ptr[2] << 8) | (ptr[3]);
//printf("decompress_subtitle 30 even=0x%x odd=0x%x\n", even_offset, odd_offset);
                ptr += 4;
                break;

            case 0xff:
                done = 1;
                break;

            default:
//					printf("unknown type %02x\n", type);
                break;
            }
        }
    }



    /* Allocate image buffer */
    subtitle->image_y = (unsigned char*)calloc(1, subtitle->w * subtitle->h + subtitle->w);
    subtitle->image_u = (unsigned char*)calloc(1, subtitle->w * subtitle->h + subtitle->w);
    subtitle->image_v = (unsigned char*)calloc(1, subtitle->w * subtitle->h + subtitle->w);
    subtitle->image_a = (unsigned char*)calloc(1, subtitle->w * subtitle->h + subtitle->w);

    /* Decode image */
    int current_nibble = 0;
    int x = 0, y = 0, field = 0;
    ptr = data_start;
    int first_pixel = 1;

    while(ptr < end && y < subtitle->h + 1 && x < subtitle->w)
    {

// Start new field based on offset, not total lines
        if(ptr - data_start >= odd_offset - 4 &&
                field == 0)
        {
// Only decode even field because too many bugs
#ifdef USE_INTERLACE
            field = 1;
#ifndef SWAP_FIELDS
            y = FIELD_OFFSET1;
#endif
            x = 0;

            if(current_nibble)
            {
                ptr++;
                current_nibble = 0;
            }
#else
            break;
#endif
        }

        unsigned int code = get_nibble(&ptr, &current_nibble);
        if(code < 0x4 && ptr < end)
        {
            code = (code << 4) | get_nibble(&ptr, &current_nibble);
            if(code < 0x10 && ptr < end)
            {
                code = (code << 4) | get_nibble(&ptr, &current_nibble);
                if(code < 0x40 && ptr < end)
                {
                    code = (code << 4) | get_nibble(&ptr, &current_nibble);
                    /* carriage return */
                    if(code < 0x4 && ptr < end)
                        code |= (subtitle->w - x) << 2;
                }
            }
        }

        int color = (code & 0x3);
        int len = code >> 2;
//if(len == 0 || len >= subtitle->w - x) printf("%d\n", len);
        if(len > subtitle->w - x)
            len = subtitle->w - x;

        int y_color = file->palette[subtitle->palette[color] * 4 + 0];
        int u_color = file->palette[subtitle->palette[color] * 4 + 1];
        int v_color = file->palette[subtitle->palette[color] * 4 + 2];
        int a_color = subtitle->alpha[color];

// The alpha seems to be arbitrary.  Assume the top left pixel is always
// transparent.
        if(first_pixel)
        {
            subtitle->alpha[color] = 0x0;
            a_color = 0x0;
            first_pixel = 0;
        }

        /*
         * printf("0x%02x 0x%02x 0x%02x\n",
         * y_color,
         * u_color,
         * v_color);
         */
        if(y < subtitle->h - 1)
        {
            for(i = 0; i < len; i++)
            {
                subtitle->image_y[y * subtitle->w + x] = y_color;
                subtitle->image_u[y * subtitle->w + x] = u_color;
                subtitle->image_v[y * subtitle->w + x] = v_color;
                subtitle->image_a[y * subtitle->w + x] = a_color;
#ifndef USE_INTERLACE
                subtitle->image_y[(y + 1) * subtitle->w + x] = y_color;
                subtitle->image_u[(y + 1) * subtitle->w + x] = u_color;
                subtitle->image_v[(y + 1) * subtitle->w + x] = v_color;
                subtitle->image_a[(y + 1) * subtitle->w + x] = a_color;
#endif
                x++;
            }
        }

        if(x >= subtitle->w)
        {
            x = 0;
            y += 2;

            /* Byte alignment */
            if(current_nibble)
            {
                ptr++;
                current_nibble = 0;
            }

// Clamp y
            if(y >= subtitle->h)
            {
#ifdef SWAP_FIELDS
                y++;
#endif
                while(y >= subtitle->h) y -= subtitle->h;
            }
        }
    }

#if 1
// Normalize image colors
    float min_h = 360;
    float max_h = 0;
    float threshold;
#define HISTOGRAM_SIZE 1000
// Decompression coefficients straight out of jpeglib
#define V_TO_R    1.40200
#define V_TO_G    -0.71414

#define U_TO_G    -0.34414
#define U_TO_B    1.77200
    unsigned char histogram[HISTOGRAM_SIZE];
    bzero(histogram, HISTOGRAM_SIZE);
    for(pass = 0; pass < 2; pass++)
    {
        for(i = 0; i < subtitle->h; i++)
        {
            for(j = 0; j < subtitle->w; j++)
            {
                if(subtitle->image_a[i * subtitle->w + j])
                {
                    unsigned char *y_color = subtitle->image_y + i * subtitle->w + j;
                    unsigned char *u_color = subtitle->image_u + i * subtitle->w + j;
                    unsigned char *v_color = subtitle->image_v + i * subtitle->w + j;
                    unsigned char *a_color = subtitle->image_a + i * subtitle->w + j;

// Convert to RGB
                    float r = (*y_color + *v_color * V_TO_R);
                    float g = (*y_color + *u_color * U_TO_G + *v_color * V_TO_G);
                    float b = (*y_color + *u_color * U_TO_B);

// Multiply alpha
                    /*
                     * 					r = r * *a_color / 0xff;
                     * 					g = g * *a_color / 0xff;
                     * 					b = b * *a_color / 0xff;
                     */

// Convert to HSV
                    float h, s, v;
                    float min, max, delta;
                    float f, p, q, t;
                    min = ((r < g) ? r : g) < b ? ((r < g) ? r : g) : b;
                    max = ((r > g) ? r : g) > b ? ((r > g) ? r : g) : b;
                    v = max;

                    delta = max - min;

                    if(max != 0 && delta != 0)
                    {
                        s = delta / max;               // s

                        if(r == max)
                            h = (g - b) / delta;         // between yellow & magenta
                        else if(g == max)
                            h = 2 + (b - r) / delta;     // between cyan & yellow
                        else
                            h = 4 + (r - g) / delta;     // between magenta & cyan

                        h *= 60;                               // degrees
                        if(h < 0)
                            h += 360;
                    }
                    else
                    {
                        // r = g = b = 0                // s = 0, v is undefined
                        s = 0;
                        h = -1;
                    }


                    /*
                     * 					int magnitude = (int)(*y_color * *y_color +
                     * 						*u_color * *u_color +
                     * 						*v_color * *v_color);
                     */

// Multiply alpha
                    h = h * *a_color / 0xff;

                    if(pass == 0)
                    {
                        histogram[(int)h]++;
                        if(h < min_h) min_h = h;
                        if(h > max_h) max_h = h;
                    }
                    else
                    {
// Set new color in a 2x2 pixel block
#ifdef MONOCHROME
                        if(h > threshold)
                        {
                            *y_color = 0xff;
                        }
                        else
                        {
                            *y_color = 0;
                        }

                        *u_color = 0x80;
                        *v_color = 0x80;

#endif

                        *a_color = 0xff;
                    }
                }
            }
        }

        if(pass == 0)
        {
            /*
             * 			int hist_total = 0;
             * 			for(i = 0; i < HISTOGRAM_SIZE; i++)
             * 			{
             * 				hist_total += histogram[i];
             * 			}
             *
             * 			int hist_count = 0;
             * 			for(i = 0; i < HISTOGRAM_SIZE; i++)
             * 			{
             * 				hist_count += histogram[i];
             * 				if(hist_count > hist_total * 1 / 3)
             * 				{
             * 					threshold = i;
             * 					break;
             * 				}
             * 			}
             */
            threshold = (min_h + max_h) / 2;
//			threshold = 324;
//printf("min_h=%f max_h=%f threshold=%f\n", min_h, max_h, threshold);
        }
    }
#endif // 0



    /*
     * printf("decompress_subtitle coords: %d,%d - %d,%d size: %d,%d start_time=%d end_time=%d\n",
     * subtitle->x1,
     * subtitle->y1,
     * subtitle->x2,
     * subtitle->y2,
     * subtitle->w,
     * subtitle->h,
     * subtitle->start_time,
     * subtitle->stop_time);
     */
    return 0;
}