示例#1
0
文件: http2.cpp 项目: choury/sproxy
/* ping 帧永远插到最前面*/
void Http2Base::PushFrame(Http2_header *header){
    uint32_t id = HTTP2_ID(header->id);
    LOGD(DHTTP2, "push a frame [%d]:%d, size:%d, flags: %d\n", id, header->type, get24(header->length), header->flags);
    std::list<write_block>::insert_iterator i;
    if((http2_flag & HTTP2_FLAG_INITED) == 0){
        i = queue_end();
        goto ret;
    }
    switch(header->type){
    case PING_TYPE:
        for(i = queue_head(); i!= queue_end() ; i++){
            if(i->offset){
                continue;
            }
            const Http2_header* check = (const Http2_header*)i->buff;
            if(check->type != PING_TYPE){
                break;
            }
        }
        break;
    case HEADERS_TYPE:{
        auto j = queue_end();
        do{
            i = j--;
            if(j == queue_head() || j->offset){
                break;
            }

            const Http2_header* check = (const Http2_header*)j->buff;
            if(check->type != DATA_TYPE)
                break;
            uint32_t jid = HTTP2_ID(check->id);
            if(jid == 0 || jid == id)
                break;
        }while(true);
        break;
    }
    default:
        i = queue_end();
        break;
    }
ret:
    size_t length = sizeof(Http2_header) + get24(header->length);
    assert(i == queue_end() || i == queue_head() || i->offset == 0);
    queue_insert(i, write_block{header, length, 0});
}
示例#2
0
文件: http2.cpp 项目: choury/sproxy
void Http2Base::SettingsProc(const Http2_header* header) {
    const Setting_Frame *sf = (const Setting_Frame *)(header + 1);
    if((header->flags & ACK_F) == 0) {
        while((char *)sf-(char *)(header+1) < get24(header->length)){
            uint32_t value = get32(sf->value);
            switch(get16(sf->identifier)){
            case SETTINGS_HEADER_TABLE_SIZE:
                LOGD(DHTTP2, "set head table size:%d\n", value);
                request_table.set_dynamic_table_size_limit_max(value);
                break;
            case SETTINGS_INITIAL_WINDOW_SIZE:
                if(value >= (uint32_t)1<<31u){
                    LOGE("ERROR window overflow\n");
                    ErrProc(ERR_FLOW_CONTROL_ERROR);
                    return;
                }
                AdjustInitalFrameWindowSize((ssize_t)value - (ssize_t)remoteframewindowsize);
                remoteframewindowsize = value;
                LOGD(DHTTP2, "set inital frame window size:%d\n", remoteframewindowsize);
                break;
            case SETTINGS_MAX_FRAME_SIZE:
                if(value > 0xffffff || value < FRAMEBODYLIMIT){
                    LOGE("ERROR frame size overflow\n");
                    ErrProc(ERR_FRAME_SIZE_ERROR);
                    return;
                }
                remoteframebodylimit = value;
                LOGD(DHTTP2, "set frame body size limit: %d\n", remoteframebodylimit);
                break;
            default:
                LOG("Get a unkown setting(%d): %d\n", get16(sf->identifier), value);
                break;
            }
            sf++;
        }
        Http2_header *header_back = (Http2_header *)p_memdup(header, sizeof(Http2_header));
        set24(header_back->length, 0);
        header_back->flags |= ACK_F;
        PushFrame(header_back);
    }else if(get24(header->length) != 0){
        LOGE("ERROR setting ack with content\n");
        ErrProc(ERR_FRAME_SIZE_ERROR);
    }
}
示例#3
0
文件: http2.cpp 项目: choury/sproxy
int Http2Base::SendFrame(){
    while(!framequeue.empty()){
        Http2_frame& frame = framequeue.front();
        size_t len = sizeof(Http2_header) + get24(frame.header->length);
        assert(get24(frame.header->length) <= FRAMEBODYLIMIT);
        ssize_t ret = Write((char *)frame.header + frame.wlen, len - frame.wlen);

        if (ret <= 0) {
            return ret;
        }

        framelen -= ret;
        if ((size_t)ret + frame.wlen == len) {
            p_free(frame.header);
            framequeue.pop_front();
        } else {
            frame.wlen += ret;
            break;
        }
    }
    return 1;
}
示例#4
0
SANE_Status
get_buffer_status (struct scanner * s, unsigned *data_avalible)
{
  SANE_Status status;
  struct cmd c = {
    {0}, 10,
    NULL, 12,
    CMD_IN
  };
  c.cmd[0] = GET_BUFFER_STATUS;
  c.cmd[7] = 12;

  status = send_command (s, &c);
  if (status)
    return status;
  *data_avalible = get24 ((unsigned char *)c.data + 9);
  return SANE_STATUS_GOOD;
}
示例#5
0
int
mem_gray8_rgb24_strip_copy_rop(gx_device * dev,
             const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
                               const gx_color_index * scolors,
           const gx_strip_bitmap * textures, const gx_color_index * tcolors,
                               int x, int y, int width, int height,
                       int phase_x, int phase_y, gs_logical_operation_t lop)
{
    gx_device_memory *mdev = (gx_device_memory *) dev;
    gs_rop3_t rop = lop_rop(lop);
    gx_color_index const_source = gx_no_color_index;
    gx_color_index const_texture = gx_no_color_index;
    uint draster = mdev->raster;
    int line_count;
    byte *drow, *base;
    int depth = dev->color_info.depth;
    int bpp = depth >> 3;       /* bytes per pixel, 1 or 3 */
    gx_color_index all_ones = ((gx_color_index) 1 << depth) - 1;
    gx_color_index strans =
        (lop & lop_S_transparent ? all_ones : gx_no_color_index);
    gx_color_index ttrans =
        (lop & lop_T_transparent ? all_ones : gx_no_color_index);
#ifdef USE_RUN_ROP
    rop_run_op ropper;
#ifdef COMPARE_AND_CONTRAST
    static byte testbuffer[4096];
    static byte *start;
    static int bytelen;
#endif
#endif

    /* Check for constant source. */
    if (!rop3_uses_S(rop))
        const_source = 0;       /* arbitrary */
    else if (scolors != 0 && scolors[0] == scolors[1]) {
        /* Constant source */
        const_source = scolors[0];
        if (const_source == gx_device_black(dev))
            rop = rop3_know_S_0(rop);
        else if (const_source == gx_device_white(dev))
            rop = rop3_know_S_1(rop);
    }

    /* Check for constant texture. */
    if (!rop3_uses_T(rop))
        const_texture = 0;      /* arbitrary */
    else if (tcolors != 0 && tcolors[0] == tcolors[1]) {
        /* Constant texture */
        const_texture = tcolors[0];
        if (const_texture == gx_device_black(dev))
            rop = rop3_know_T_0(rop);
        else if (const_texture == gx_device_white(dev))
            rop = rop3_know_T_1(rop);
    }

    if (bpp == 1 &&
        (gx_device_has_color(dev) ||
         (gx_device_black(dev) != 0 || gx_device_white(dev) != all_ones))
        ) {
        /*
         * This is an 8-bit device but not gray-scale.  Except in a few
         * simple cases, we have to use the slow algorithm that converts
         * values to and from RGB.
         */
        gx_color_index bw_pixel;

        switch (rop) {
        case rop3_0:
            bw_pixel = gx_device_black(dev);
            goto bw;
        case rop3_1:
            bw_pixel = gx_device_white(dev);
bw:         if (bw_pixel == 0x00)
                rop = rop3_0;
            else if (bw_pixel == 0xff)
                rop = rop3_1;
            else
                goto df;
            break;
        case rop3_D:
            break;
        case rop3_S:
            if (lop & lop_S_transparent)
                goto df;
            break;
        case rop3_T:
            if (lop & lop_T_transparent)
                goto df;
            break;
        default:
df:         return mem_default_strip_copy_rop(dev,
                                              sdata, sourcex, sraster, id,
                                              scolors, textures, tcolors,
                                              x, y, width, height,
                                              phase_x, phase_y, lop);
        }
    }

    /* Adjust coordinates to be in bounds. */
    if (const_source == gx_no_color_index) {
        fit_copy(dev, sdata, sourcex, sraster, id,
                 x, y, width, height);
    } else {
        fit_fill(dev, x, y, width, height);
    }

    /* Set up transfer parameters. */
    line_count = height;
    base = scan_line_base(mdev, y);
    drow = base + x * bpp;

    /*
     * There are 18 cases depending on whether each of the source and
     * texture is constant, 1-bit, or multi-bit, and on whether the
     * depth is 8 or 24 bits.  We divide first according to constant
     * vs. non-constant, and then according to 1- vs. multi-bit, and
     * finally according to pixel depth.  This minimizes source code,
     * but not necessarily time, since we do some of the divisions
     * within 1 or 2 levels of loop.
     */

#ifdef USE_RUN_ROP
#define dbit(base, i) ((base)[(i) >> 3] & (0x80 >> ((i) & 7)))
/* 8-bit */
#define cbit8(base, i, colors)\
  (dbit(base, i) ? (byte)colors[1] : (byte)colors[0])
#define rop_body_8(s_pixel, t_pixel)\
  if ( (s_pixel) == strans ||   /* So = 0, s_tr = 1 */\
       (t_pixel) == ttrans      /* Po = 0, p_tr = 1 */\
     )\
    continue;\
  *dptr = (*rop_proc_table[rop])(*dptr, s_pixel, t_pixel)
/* 24-bit */
#define get24(ptr)\
  (((gx_color_index)(ptr)[0] << 16) | ((gx_color_index)(ptr)[1] << 8) | (ptr)[2])
#define put24(ptr, pixel)\
  (ptr)[0] = (byte)((pixel) >> 16),\
  (ptr)[1] = (byte)((uint)(pixel) >> 8),\
  (ptr)[2] = (byte)(pixel)
#define cbit24(base, i, colors)\
  (dbit(base, i) ? colors[1] : colors[0])
#define rop_body_24(s_pixel, t_pixel)\
  if ( (s_pixel) == strans ||   /* So = 0, s_tr = 1 */\
       (t_pixel) == ttrans      /* Po = 0, p_tr = 1 */\
     )\
    continue;\
  { gx_color_index d_pixel = get24(dptr);\
    d_pixel = (*rop_proc_table[rop])(d_pixel, s_pixel, t_pixel);\
    put24(dptr, d_pixel);\
  }
    if (const_texture != gx_no_color_index) {
/**** Constant texture ****/
        if (const_source != gx_no_color_index) {
/**** Constant source & texture ****/
            rop_get_run_op(&ropper, lop, depth, rop_s_constant | rop_t_constant);
            rop_set_s_constant(&ropper, const_source);
            rop_set_t_constant(&ropper, const_texture);
            for (; line_count-- > 0; drow += draster) {
#ifdef COMPARE_AND_CONTRAST
                byte *dptr = drow;
                int left = width;

                bytelen = left*bpp; start = dptr;
                memcpy(testbuffer, dptr, bytelen);
                rop_run(&ropper, testbuffer, left);

                if (bpp == 1)
/**** 8-bit destination ****/
                    for (; left > 0; ++dptr, --left) {
                        vd_pixel(int2fixed((dptr - base) % draster),
                                 int2fixed((dptr - base) / draster + y), const_texture);
                        rop_body_8((byte)const_source, (byte)const_texture);
                    }
                else
/**** 24-bit destination ****/
                    for (; left > 0; dptr += 3, --left) {
                        vd_pixel(int2fixed((dptr - base) % draster / 3),
                                 int2fixed((dptr - base) / draster + y), const_texture);
                        rop_body_24(const_source, const_texture);
                    }
                if (memcmp(testbuffer, start, bytelen) != 0) {
                    eprintf("Failed!\n");
                }
#else
                rop_run(&ropper, drow, width);
#endif
            }
            rop_release_run_op(&ropper);
        } else {
/**** Data source, const texture ****/
            if (scolors) {
                const byte *srow = sdata;

                rop_get_run_op(&ropper, lop, depth, rop_t_constant | rop_s_1bit);
                rop_set_t_constant(&ropper, const_texture);
                rop_set_s_colors(&ropper, scolors);

                for (; line_count-- > 0; drow += draster, srow += sraster) {
#ifdef COMPARE_AND_CONTRAST
                    byte *dptr = drow;
                    int left = width;
/**** 1-bit source ****/
                    int sx = sourcex;

                    rop_set_s_bitmap_subbyte(&ropper, srow, sourcex);
                    bytelen = left*bpp; start = dptr;
                    memcpy(testbuffer, dptr, bytelen);
                    rop_run(&ropper, testbuffer, width);
                    if (bpp == 1)
/**** 8-bit destination ****/
                        for (; left > 0; ++dptr, ++sx, --left) {
                            byte s_pixel = cbit8(srow, sx, scolors);

                            vd_pixel(int2fixed((dptr - base) % draster),
                                 int2fixed((dptr - base) / draster + y), const_texture);
                            rop_body_8(s_pixel, (byte)const_texture);
                        }
                    else
/**** 24-bit destination ****/
                        for (; left > 0; dptr += 3, ++sx, --left) {
                            bits32 s_pixel = cbit24(srow, sx, scolors);

                            vd_pixel(int2fixed((dptr - base) % draster / 3),
                                 int2fixed((dptr - base) / draster + y), const_texture);
                            rop_body_24(s_pixel, const_texture);
                        }
                    if (memcmp(testbuffer, start, bytelen) != 0) {
                        eprintf("Failed!\n");
                    }
#else
/**** 1-bit source ****/
/**** 8-bit destination ****/
/**** 24-bit destination ****/
                    rop_set_s_bitmap_subbyte(&ropper, srow, sourcex);
                    rop_run(&ropper, drow, width);
#endif
                }
                rop_release_run_op(&ropper);
            } else {
                const byte *srow = sdata;
                rop_get_run_op(&ropper, lop, depth, rop_t_constant);
                rop_set_t_constant(&ropper, const_texture);
                for (; line_count-- > 0; drow += draster, srow += sraster) {
#ifdef COMPARE_AND_CONTRAST
                    byte *dptr = drow;
                    int left = width;

                    bytelen = left*bpp; start = dptr;
                    memcpy(testbuffer, dptr, bytelen);

                    rop_set_s_bitmap(&ropper, srow + sourcex * bpp);
                    rop_run(&ropper, testbuffer, left);
/**** 8-bit source & dest ****/
                    if (bpp == 1) {
                        const byte *sptr = srow + sourcex;

                        for (; left > 0; ++dptr, ++sptr, --left) {
                            byte s_pixel = *sptr;

                            vd_pixel(int2fixed((dptr - base) % draster),
                                     int2fixed((dptr - base) / draster + y), const_texture);
                            rop_body_8(s_pixel, (byte)const_texture);
                        }
                    } else {
/**** 24-bit source & dest ****/
                        const byte *sptr = srow + sourcex * 3;

                        bytelen = left*bpp; start = dptr;
                        memcpy(testbuffer, dptr, bytelen);

                        for (; left > 0; dptr += 3, sptr += 3, --left) {
                            bits32 s_pixel = get24(sptr);

                            vd_pixel(int2fixed((dptr - base) % draster / 3),
                                     int2fixed((dptr - base) / draster + y), const_texture);
                            rop_body_24(s_pixel, const_texture);
                        }
                    }
                    if (memcmp(testbuffer, start, bytelen) != 0) {
                        eprintf("Failed!\n");
                    }
#else
/**** 8-bit source & dest ****/
/**** 24-bit source & dest ****/
                    rop_set_s_bitmap(&ropper, srow + sourcex * bpp);
                    rop_run(&ropper, drow, width);
#endif
                }
                rop_release_run_op(&ropper);
            }
        }
    } else if (const_source != gx_no_color_index) {
/**** Const source, data texture ****/
        if (tcolors) {
            uint traster = textures->raster;
            int ty = y + phase_y;

            rop_get_run_op(&ropper, lop, depth, rop_s_constant | rop_t_1bit);
            rop_set_s_constant(&ropper, const_source);
            for (; line_count-- > 0; drow += draster, ++ty) {   /* Loop over copies of the tile. */
                int dx = x, w = width, nw;
                byte *dptr = drow;
                const byte *trow =
                textures->data + (ty % textures->size.y) * traster;
                int xoff = x_offset(phase_x, ty, textures);

                for (; w > 0; dx += nw, w -= nw) {
                    int tx = (dx + xoff) % textures->rep_width;
                    int left = nw = min(w, textures->size.x - tx);
                    const byte *tptr = trow;

                    rop_set_t_bitmap_subbyte(&ropper, trow, tx);
#ifdef COMPARE_AND_CONTRAST
                    bytelen = left*bpp; start = dptr;
                    memcpy(testbuffer, dptr, bytelen);
                    rop_run(&ropper, testbuffer, left);
/**** 1-bit texture ****/
                    if (bpp == 1)
/**** 8-bit dest ****/
                        for (; left > 0; ++dptr, ++tx, --left) {
                            byte t_pixel = cbit8(tptr, tx, tcolors);

                            vd_pixel(int2fixed((dptr - base) % draster),
                                 int2fixed((dptr - base) / draster + y), t_pixel);
                            rop_body_8((byte)const_source, t_pixel);
                        }
                    else
/**** 24-bit dest ****/
                        for (; left > 0; dptr += 3, ++tx, --left) {
                            bits32 t_pixel = cbit24(tptr, tx, tcolors);

                            vd_pixel(int2fixed((dptr - base) % draster / 3),
                                 int2fixed((dptr - base) / draster + y), t_pixel);
                            rop_body_24(const_source, t_pixel);
                        }
                    if (memcmp(testbuffer, start, bytelen) != 0) {
                        eprintf("Failed!\n");
                    }
#else
                    rop_run(&ropper, dptr, left);
                    dptr += left;
#endif
                }
            }
        } else {
            uint traster = textures->raster;
            int ty = y + phase_y;

            rop_get_run_op(&ropper, lop, depth, rop_s_constant);
            rop_set_s_constant(&ropper, const_source);

            for (; line_count-- > 0; drow += draster, ++ty) {   /* Loop over copies of the tile. */
                int dx = x, w = width, nw;
                byte *dptr = drow;
                const byte *trow =
                textures->data + (ty % textures->size.y) * traster;
                int xoff = x_offset(phase_x, ty, textures);

                for (; w > 0; dx += nw, w -= nw) {
                    int tx = (dx + xoff) % textures->rep_width;
                    int left = nw = min(w, textures->size.x - tx);
                    const byte *tptr = trow + tx*bpp;
                    rop_set_t_bitmap(&ropper, tptr);
#ifdef COMPARE_AND_CONTRAST
                    bytelen = left*bpp; start = dptr;
                    memcpy(testbuffer, dptr, bytelen);
                    rop_run(&ropper, testbuffer, left);
/**** 8-bit T & D ****/
                    if (bpp == 1) {
                        for (; left > 0; ++dptr, ++tptr, --left) {
                            byte t_pixel = *tptr;

                            vd_pixel(int2fixed((dptr - base) % draster),
                                    int2fixed((dptr - base) / draster + y), t_pixel);
                            rop_body_8((byte)const_source, t_pixel);
                        }
                    } else {
/**** 24-bit T & D ****/
                        for (; left > 0; dptr += 3, tptr += 3, --left) {
                            bits32 t_pixel = get24(tptr);

                            vd_pixel(int2fixed((dptr - base) % draster / 3),
                                     int2fixed((dptr - base) / draster + y), t_pixel);
                            rop_body_24(const_source, t_pixel);
                        }
                    }
                    if (memcmp(testbuffer, start, bytelen) != 0) {
                        eprintf("Failed!\n");
                    }
#else
/**** 8-bit T & D ****/
/**** 24-bit T & D ****/
                    rop_run(&ropper, dptr, left);
                    dptr += left * bpp;
#endif
                }
            }
            rop_release_run_op(&ropper);
        }
    } else {
/**** Data source & texture ****/
        if (scolors != NULL | tcolors != NULL) {
            uint traster = textures->raster;
            int ty = y + phase_y;
            const byte *srow = sdata;

            rop_get_run_op(&ropper, lop, depth,
                           ((scolors == NULL ? 0 : rop_s_1bit) |
                            (tcolors == NULL ? 0 : rop_t_1bit)));

            /* Loop over scan lines. */
            for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) {  /* Loop over copies of the tile. */
                int sx = sourcex;
                int dx = x;
                int w = width;
                int nw;
                byte *dptr = drow;
                const byte *trow =
                textures->data + (ty % textures->size.y) * traster;
                int xoff = x_offset(phase_x, ty, textures);

                for (; w > 0; dx += nw, w -= nw) {      /* Loop over individual pixels. */
                    int tx = (dx + xoff) % textures->rep_width;
                    int left = nw = min(w, textures->size.x - tx);
                    const byte *sptr = srow + sx*bpp;
                    const byte *tptr = trow + tx*bpp;

                    /*
                     * For maximum speed, we should split this loop
                     * into 7 cases depending on source & texture
                     * depth: (1,1), (1,8), (1,24), (8,1), (8,8),
                     * (24,1), (24,24).  But since we expect these
                     * cases to be relatively uncommon, we just
                     * divide on the destination depth.
                     */
                    if (scolors)
                        rop_set_s_bitmap_subbyte(&ropper, srow, sx);
                    else
                        rop_set_s_bitmap(&ropper, sptr);
                    if (tcolors)
                        rop_set_t_bitmap_subbyte(&ropper, trow, tx);
                    else
                        rop_set_t_bitmap(&ropper, tptr);

#ifdef COMPARE_AND_CONTRAST
                    bytelen = left*bpp; start = dptr;
                    memcpy(testbuffer, dptr, bytelen);
                    rop_run(&ropper, testbuffer, left);
                    if (bpp == 1) {
/**** 8-bit destination ****/
                        for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) {
                            byte s_pixel =
                                (scolors ? cbit8(srow, sx, scolors) : *sptr);
                            byte t_pixel =
                                (tcolors ? cbit8(trow, tx, tcolors) : *tptr);

                            vd_pixel(int2fixed((dptr - base) % draster),
                                     int2fixed((dptr - base) / draster + y), t_pixel);
                            rop_body_8(s_pixel, t_pixel);
                        }
                    } else {
/**** 24-bit destination ****/
                        for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) {
                            bits32 s_pixel =
                                (scolors ? cbit24(srow, sx, scolors) :
                                 get24(sptr));
                            bits32 t_pixel =
                                (tcolors ? cbit24(tptr, tx, tcolors) :
                                 get24(tptr));

                            vd_pixel(int2fixed((dptr - base) % draster / 3),
                                     int2fixed((dptr - base) / draster + y), t_pixel);
                            rop_body_24(s_pixel, t_pixel);
                        }
                    }
                    if (memcmp(testbuffer, start, bytelen) != 0) {
                        eprintf("Failed!\n");
                    }
#else
                    rop_run(&ropper, dptr, left);
#endif
                }
            }
        } else {
            uint traster = textures->raster;
            int ty = y + phase_y;
            const byte *srow = sdata;

            /* Loop over scan lines. */
            rop_get_run_op(&ropper, rop, depth, 0);
            for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) {  /* Loop over copies of the tile. */
                int sx = sourcex;
                int dx = x;
                int w = width;
                int nw;
                byte *dptr = drow;
                const byte *trow =
                textures->data + (ty % textures->size.y) * traster;
                int xoff = x_offset(phase_x, ty, textures);

                for (; w > 0; dx += nw, w -= nw) {      /* Loop over individual pixels. */
                    int tx = (dx + xoff) % textures->rep_width;
                    int left = nw = min(w, textures->size.x - tx);
                    const byte *tptr = trow + tx * bpp;
                    const byte *sptr = srow + sx * bpp;

                    rop_set_s_bitmap(&ropper, sptr);
                    rop_set_t_bitmap(&ropper, tptr);
#ifdef COMPARE_AND_CONTRAST
                    if (bpp == 1) {
                        rop_run(&ropper, testbuffer, left);
/**** 8-bit destination ****/

                        for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) {
                            rop_body_8(*sptr, *tptr);
                        }
                    } else {
/**** 24-bit destination ****/
                        for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) {
                            bits32 s_pixel = get24(sptr);
                            bits32 t_pixel = get24(tptr);

                            rop_body_24(s_pixel, t_pixel);
                        }
                    }
                    if (memcmp(testbuffer, start, bytelen) != 0) {
                        eprintf("Failed!\n");
                    }
#else
/**** 8-bit destination ****/
/**** 24-bit destination ****/
                    rop_run(&ropper, dptr, left);
#endif
                }
            }
            rop_release_run_op(&ropper);
        }
    }
#undef rop_body_8
#undef rop_body_24
#undef dbit
#undef cbit8
#undef cbit24
#else

#define dbit(base, i) ((base)[(i) >> 3] & (0x80 >> ((i) & 7)))
/* 8-bit */
#define cbit8(base, i, colors)\
  (dbit(base, i) ? (byte)colors[1] : (byte)colors[0])
#define rop_body_8(s_pixel, t_pixel)\
  if ( (s_pixel) == strans ||   /* So = 0, s_tr = 1 */\
       (t_pixel) == ttrans      /* Po = 0, p_tr = 1 */\
     )\
    continue;\
  *dptr = (*rop_proc_table[rop])(*dptr, s_pixel, t_pixel)
/* 24-bit */
#define get24(ptr)\
  (((gx_color_index)(ptr)[0] << 16) | ((gx_color_index)(ptr)[1] << 8) | (ptr)[2])
#define put24(ptr, pixel)\
  (ptr)[0] = (byte)((pixel) >> 16),\
  (ptr)[1] = (byte)((uint)(pixel) >> 8),\
  (ptr)[2] = (byte)(pixel)
#define cbit24(base, i, colors)\
  (dbit(base, i) ? colors[1] : colors[0])
#define rop_body_24(s_pixel, t_pixel)\
  if ( (s_pixel) == strans ||   /* So = 0, s_tr = 1 */\
       (t_pixel) == ttrans      /* Po = 0, p_tr = 1 */\
     )\
    continue;\
  { gx_color_index d_pixel = get24(dptr);\
    d_pixel = (*rop_proc_table[rop])(d_pixel, s_pixel, t_pixel);\
    put24(dptr, d_pixel);\
  }

    if (const_texture != gx_no_color_index) {
/**** Constant texture ****/
        if (const_source != gx_no_color_index) {
/**** Constant source & texture ****/
            for (; line_count-- > 0; drow += draster) {
                byte *dptr = drow;
                int left = width;

                if (bpp == 1)
/**** 8-bit destination ****/
                    for (; left > 0; ++dptr, --left) {
                        vd_pixel(int2fixed((dptr - base) % draster),
                                 int2fixed((dptr - base) / draster + y), const_texture);
                        rop_body_8((byte)const_source, (byte)const_texture);
                    }
                else
/**** 24-bit destination ****/
                    for (; left > 0; dptr += 3, --left) {
                        vd_pixel(int2fixed((dptr - base) % draster / 3),
                                 int2fixed((dptr - base) / draster + y), const_texture);
                        rop_body_24(const_source, const_texture);
                    }
            }
        } else {
/**** Data source, const texture ****/
            const byte *srow = sdata;

            for (; line_count-- > 0; drow += draster, srow += sraster) {
                byte *dptr = drow;
                int left = width;

                if (scolors) {
/**** 1-bit source ****/
                    int sx = sourcex;

                    if (bpp == 1)
/**** 8-bit destination ****/
                        for (; left > 0; ++dptr, ++sx, --left) {
                            byte s_pixel = cbit8(srow, sx, scolors);

                            vd_pixel(int2fixed((dptr - base) % draster),
                                 int2fixed((dptr - base) / draster + y), const_texture);
                            rop_body_8(s_pixel, (byte)const_texture);
                        }
                    else
/**** 24-bit destination ****/
                        for (; left > 0; dptr += 3, ++sx, --left) {
                            bits32 s_pixel = cbit24(srow, sx, scolors);

                            vd_pixel(int2fixed((dptr - base) % draster / 3),
                                 int2fixed((dptr - base) / draster + y), const_texture);
                            rop_body_24(s_pixel, const_texture);
                        }
                } else if (bpp == 1) {
/**** 8-bit source & dest ****/
                    const byte *sptr = srow + sourcex;

                    for (; left > 0; ++dptr, ++sptr, --left) {
                        byte s_pixel = *sptr;

                        vd_pixel(int2fixed((dptr - base) % draster),
                                 int2fixed((dptr - base) / draster + y), const_texture);
                        rop_body_8(s_pixel, (byte)const_texture);
                    }
                } else {
/**** 24-bit source & dest ****/
                    const byte *sptr = srow + sourcex * 3;

                    for (; left > 0; dptr += 3, sptr += 3, --left) {
                        bits32 s_pixel = get24(sptr);

                        vd_pixel(int2fixed((dptr - base) % draster / 3),
                                 int2fixed((dptr - base) / draster + y), const_texture);
                        rop_body_24(s_pixel, const_texture);
                    }
                }
            }
        }
    } else if (const_source != gx_no_color_index) {
/**** Const source, data texture ****/
        uint traster = textures->raster;
        int ty = y + phase_y;

        for (; line_count-- > 0; drow += draster, ++ty) {       /* Loop over copies of the tile. */
            int dx = x, w = width, nw;
            byte *dptr = drow;
            const byte *trow =
            textures->data + (ty % textures->size.y) * traster;
            int xoff = x_offset(phase_x, ty, textures);

            for (; w > 0; dx += nw, w -= nw) {
                int tx = (dx + xoff) % textures->rep_width;
                int left = nw = min(w, textures->size.x - tx);
                const byte *tptr = trow;

                if (tcolors) {
/**** 1-bit texture ****/
                    if (bpp == 1)
/**** 8-bit dest ****/
                        for (; left > 0; ++dptr, ++tx, --left) {
                            byte t_pixel = cbit8(tptr, tx, tcolors);

                            vd_pixel(int2fixed((dptr - base) % draster),
                                 int2fixed((dptr - base) / draster + y), t_pixel);
                            rop_body_8((byte)const_source, t_pixel);
                        }
                    else
/**** 24-bit dest ****/
                        for (; left > 0; dptr += 3, ++tx, --left) {
                            bits32 t_pixel = cbit24(tptr, tx, tcolors);

                            vd_pixel(int2fixed((dptr - base) % draster / 3),
                                 int2fixed((dptr - base) / draster + y), t_pixel);
                            rop_body_24(const_source, t_pixel);
                        }
                } else if (bpp == 1) {
/**** 8-bit T & D ****/
                    tptr += tx;
                    for (; left > 0; ++dptr, ++tptr, --left) {
                        byte t_pixel = *tptr;

                        vd_pixel(int2fixed((dptr - base) % draster),
                                 int2fixed((dptr - base) / draster + y), t_pixel);
                        rop_body_8((byte)const_source, t_pixel);
                    }
                } else {
/**** 24-bit T & D ****/
                    tptr += tx * 3;
                    for (; left > 0; dptr += 3, tptr += 3, --left) {
                        bits32 t_pixel = get24(tptr);

                        vd_pixel(int2fixed((dptr - base) % draster / 3),
                                 int2fixed((dptr - base) / draster + y), t_pixel);
                        rop_body_24(const_source, t_pixel);
                    }
                }
            }
        }
    } else {
/**** Data source & texture ****/
        uint traster = textures->raster;
        int ty = y + phase_y;
        const byte *srow = sdata;

        /* Loop over scan lines. */
        for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) {      /* Loop over copies of the tile. */
            int sx = sourcex;
            int dx = x;
            int w = width;
            int nw;
            byte *dptr = drow;
            const byte *trow =
            textures->data + (ty % textures->size.y) * traster;
            int xoff = x_offset(phase_x, ty, textures);

            for (; w > 0; dx += nw, w -= nw) {  /* Loop over individual pixels. */
                int tx = (dx + xoff) % textures->rep_width;
                int left = nw = min(w, textures->size.x - tx);
                const byte *tptr = trow;

                /*
                 * For maximum speed, we should split this loop
                 * into 7 cases depending on source & texture
                 * depth: (1,1), (1,8), (1,24), (8,1), (8,8),
                 * (24,1), (24,24).  But since we expect these
                 * cases to be relatively uncommon, we just
                 * divide on the destination depth.
                 */
                if (bpp == 1) {
/**** 8-bit destination ****/
                    const byte *sptr = srow + sx;

                    tptr += tx;
                    for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) {
                        byte s_pixel =
                            (scolors ? cbit8(srow, sx, scolors) : *sptr);
                        byte t_pixel =
                            (tcolors ? cbit8(tptr, tx, tcolors) : *tptr);

                        vd_pixel(int2fixed((dptr - base) % draster),
                                 int2fixed((dptr - base) / draster + y), t_pixel);
                        rop_body_8(s_pixel, t_pixel);
                    }
                } else {
/**** 24-bit destination ****/
                    const byte *sptr = srow + sx * 3;

                    tptr += tx * 3;
                    for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) {
                        bits32 s_pixel =
                            (scolors ? cbit24(srow, sx, scolors) :
                             get24(sptr));
                        bits32 t_pixel =
                            (tcolors ? cbit24(tptr, tx, tcolors) :
                             get24(tptr));

                        vd_pixel(int2fixed((dptr - base) % draster / 3),
                                 int2fixed((dptr - base) / draster + y), t_pixel);
                        rop_body_24(s_pixel, t_pixel);
                    }
                }
            }
        }
    }
#undef rop_body_8
#undef rop_body_24
#undef dbit
#undef cbit8
#undef cbit24
#endif
    return 0;
}
static ngx_int_t ngx_http_mp4frag_handler(ngx_http_request_t *r)
{
    ngx_int_t    rc;
    ngx_chain_t  out;
    u_char *resp_body;
    ngx_buf_t   *resp;
    char *lastslash;
    char *mediafilename;
    u_char *last;
    size_t root;
    ngx_str_t path;
    ngx_str_t index_map = ngx_null_string;
    const u_char *indexptr;
    ngx_str_t mediafile_map = ngx_null_string;
    unsigned medianum, fragnum;
    uint16_t nmedia;
    ngx_str_t videocodecdata, audiocodecdata;
    uint32_t mediaoffset, fragments_offset;
    uint16_t mediafilenamelen;
    uint16_t nsamples, nfragments;
    uint32_t totalsize;
    unsigned int iii;

    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
        return NGX_HTTP_NOT_ALLOWED;
    }
 
    /* discard request body, since we don't need it here */
    rc = ngx_http_discard_request_body(r);
 
    if (rc != NGX_OK) {
        return rc;
    }
 
#if 0
    /* set the 'Content-type' header */
    r->headers_out.content_type.len = sizeof("text/html") - 1;
    r->headers_out.content_type.data = (u_char *) "text/html";
#endif
 
    last = ngx_http_map_uri_to_path(r, &path, &root, 0);
    lastslash = strrchr((char*)path.data, '/');
    if ( lastslash ) {
        path.len = lastslash - (char*)path.data;
    }

    /* определить путь к файлу индекса и номер фрагмента: */
    *lastslash++ = 0;
    // uri - dirname, lastslash - basename
    if ( memcmp(lastslash, "Seg1-Frag", 9) != 0 ) {
        return NGX_HTTP_NOT_FOUND;
    }
    fragnum = atoi(lastslash + 9);

    lastslash = strrchr((char*)path.data, '/');
    if ( !lastslash ) {
        return NGX_HTTP_NOT_FOUND;
    }
    medianum = atoi(lastslash + 1);

    memcpy(lastslash + 1, "index", 6);
    
    if ( (rc = make_mapping((const char *)path.data, &index_map, r)) != NGX_OK ) {
        return rc;
    }
    indexptr = index_map.data;

#define CHECKMAP(nbytes) do { if (indexptr + nbytes >= index_map.data + index_map.len) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "index underrun, offset 0x%0x", nbytes); goto GENERAL_ERROR;}  } while(0)

    CHECKMAP(10); /* 8 for signature and 2 for media count */
    if ( memcmp(index_map.data, "mp4frag", 7) != 0 || index_map.data[7] /* version */ > 2 ) {
        free_mapping(&index_map);
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Bad index format in %s", path.data);
        goto GENERAL_ERROR;
    }
    indexptr += 8;

    nmedia = get16(indexptr);
    if ( medianum >= nmedia ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "No media #%d in %s, total %d media", medianum, path.data, nmedia);
        goto GENERAL_ERROR;
    }
    indexptr += 2;
    CHECKMAP(nmedia * 4);

    mediaoffset = get32(indexptr + medianum * 4);
    if ( mediaoffset >= index_map.len ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "short index in %s", path.data);
        goto GENERAL_ERROR;
    }
    indexptr = index_map.data;
    CHECKMAP(mediaoffset);
    indexptr = index_map.data + mediaoffset;

    CHECKMAP(2);
    mediafilenamelen = get16(indexptr);
    indexptr += 2;
    CHECKMAP(mediafilenamelen);
    if ( index_map.data[7] == 1 ) {
        if ( (mediafilename = ngx_pcalloc(r->pool, mediafilenamelen + 1)) == NULL ) {
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Insufficient memory");
            goto GENERAL_ERROR;
        }
        memcpy(mediafilename, (const char *)indexptr, mediafilenamelen);
        mediafilename[mediafilenamelen] = 0;
    }
    else /* index_map.data[7] == 2 */ {
        mediafilename = (char *)indexptr;
    }

    indexptr += mediafilenamelen;
 
    CHECKMAP(2);
    videocodecdata.len = get16(indexptr);
    indexptr += 2;
    CHECKMAP(videocodecdata.len);
    videocodecdata.data = (u_char*)indexptr;
    indexptr += videocodecdata.len;
    CHECKMAP(2);
    audiocodecdata.len = get16(indexptr);
    indexptr += 2;
    CHECKMAP(audiocodecdata.len);
    audiocodecdata.data = (u_char*)indexptr;
    indexptr += audiocodecdata.len;

    /* number of fragments in the media */
    CHECKMAP(2);
    nfragments = get16(indexptr);
    if ( fragnum > nfragments || fragnum < 1 ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "No fragment #%d in media #%d in file %s", fragnum, medianum, path.data);
        goto NOT_FOUND;
    }
    indexptr += 2;

    CHECKMAP(nfragments * 4);

    fragments_offset = get32(indexptr + (fragnum - 1) * 4);
    indexptr = index_map.data;
    CHECKMAP(fragments_offset);
    indexptr += fragments_offset;

    CHECKMAP(6);  /* first entry should present anyway */
    nsamples = get16(indexptr);
    if ( nsamples < 1 ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Number of samples is 0 for media #%d, fragment #%d, index %s",
                      medianum, fragnum, path.data);
        goto GENERAL_ERROR;
    }

    /* total fragment size in bytes: */
    totalsize = get32(indexptr + 2);

    ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "nsamples=%d, totalsize=%d", nsamples, totalsize);

    indexptr += 6;

    /* allocate memory for response */
    if ( (resp_body = ngx_pcalloc(r->pool, totalsize)) == NULL ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Insufficient memory");
        goto GENERAL_ERROR;
    }

    if ( (resp = ngx_pcalloc(r->pool, sizeof(ngx_buf_t))) == NULL ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Insufficient memory");
        goto GENERAL_ERROR;
    }
 
    out.buf = resp;
    out.next = NULL;

    resp->pos = resp_body;
    resp->last = resp_body + totalsize;
    resp->memory = 1; 
    resp->last_buf = 1;
 
    if ( make_mapping(mediafilename, &mediafile_map, r) != NGX_OK ) goto GENERAL_ERROR;
 
    /* generate the fragment */
    write32(resp_body, totalsize);
    memcpy(resp_body + 4, "mdat", 4);

    CHECKMAP(16 * nsamples - 1); /* check if the last byte still inside the index */

    /* fragment timestamp is equal to first sample timestamp */
    resp_body = write_fragment_prefix(resp_body + 8, &videocodecdata, &audiocodecdata, get32(indexptr + 8));

    for ( iii = 0; iii < nsamples; ++iii ) {
        uint32_t offset = get32(indexptr);
        uint32_t size = get32(indexptr + 4);
        uint32_t timestamp = get32(indexptr + 8);
        uint32_t composition_offset = get24(indexptr + 12);
        uint8_t flags = indexptr[15];
        indexptr += 16;
        if ( flags ) {
            resp_body = write_video_packet(resp_body, flags & 2, 0, composition_offset, timestamp,
                                     mediafile_map.data + offset, size);
        }
        else {
            resp_body = write_audio_packet(resp_body, 0, timestamp, mediafile_map.data + offset, size);
        }
    }

    free_mapping(&index_map);
    free_mapping(&mediafile_map);

    if ( resp_body != resp->last ) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "response buffer overrun");
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = totalsize;

    rc = ngx_http_send_header(r);
    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only || r->method == NGX_HTTP_HEAD) {
        return rc;
    }

    /* send the buffer chain of your response */
    return ngx_http_output_filter(r, &out);

GENERAL_ERROR:
    free_mapping(&index_map);
    free_mapping(&mediafile_map);
    return NGX_HTTP_INTERNAL_SERVER_ERROR;

NOT_FOUND:
    free_mapping(&index_map);
    free_mapping(&mediafile_map);
    return NGX_HTTP_NOT_FOUND;

}
示例#7
0
文件: http2.cpp 项目: choury/sproxy
size_t Http2Base::DefaultProc(const uchar* http2_buff, size_t len) {
    const Http2_header *header = (const Http2_header *)http2_buff;
    if(len < sizeof(Http2_header)){
        if(len)
            LOGD(DHTTP2, "get a incompleted head, size:%zu\n", len);
        return 0;
    }else{
        uint32_t length = get24(header->length);
        if(length > FRAMEBODYLIMIT){
            LOGE("ERROR frame size: %d\n", length);
            ErrProc(ERR_FRAME_SIZE_ERROR);
            return 0;
        }
        if(len < length + sizeof(Http2_header)){
            LOGD(DHTTP2, "get a incompleted packet, size:%zu/%zu\n", len, length + sizeof(Http2_header));
            return 0;
        }else{
            uint32_t id = HTTP2_ID(header->id);
            if(http2_flag & HTTP2_FLAG_GOAWAYED){
                LOG("get a frame [%d]:%d, size:%d after goaway, ignore it.\n", id, header->type, length);
                return length + sizeof(Http2_header);
            }
            LOGD(DHTTP2, "get a frame [%d]:%d, size:%d, flags:%d\n", id, header->type, length, header->flags);
            try {
                uint32_t value;
                switch(header->type) {
                case DATA_TYPE:
                    if(id == 0 || (id > recvid && id >= sendid-1)){
                        LOGE("ERROR wrong data id: %d/%d/%d\n", id, recvid, sendid);
                        ErrProc(ERR_PROTOCOL_ERROR);
                        return 0;
                    }
                    DataProc(id, header+1, length);
                    if(header->flags & END_STREAM_F){
                        EndProc(id);
                    }
                    break;
                case HEADERS_TYPE:
                    HeadersProc(header);
                    if(header->flags & END_STREAM_F){
                        EndProc(id);
                    }
                    break;
                case PRIORITY_TYPE:
                    break;
                case SETTINGS_TYPE:
                    if(id != 0 || length%6 != 0){
                        LOGE("ERROR wrong setting frame : %d/%d\n", id, length);
                        ErrProc(ERR_PROTOCOL_ERROR);
                        return 0;
                    }
                    SettingsProc(header);
                    break;
                case PING_TYPE:
                    if(id != 0 || length != 8){
                        LOGE("ERROR wrong ping frame: %d/%d\n", id, length);
                        ErrProc(ERR_FRAME_SIZE_ERROR);
                        return 0;
                    }
                    PingProc(header);
                    break;
                case GOAWAY_TYPE:
                    GoawayProc(header);
                    break;
                case RST_STREAM_TYPE:
                    value = get32(header+1);
                    if(length != 4){
                        LOGE("ERROR rst frame: %d/%d\n", id, length);
                        ErrProc(ERR_FRAME_SIZE_ERROR);
                        return 0;
                    }
                    if(id == 0 || (id > recvid && id >= sendid-1)){
                        LOGE("ERROR rst frame: %d/%d/%d\n", id, sendid, recvid);
                        ErrProc(ERR_PROTOCOL_ERROR);
                        return 0;
                    }
                    RstProc(id, value);
                    break;
                case WINDOW_UPDATE_TYPE:
                    value = get32(header+1);
                    if(length != 4){
                        LOGE("ERROR window update frame: %d/%d\n", id, length);
                        ErrProc(ERR_FRAME_SIZE_ERROR);
                        return 0;
                    }
                    if(value == 0 || (id > recvid && id >= sendid-1)){
                        LOGE("ERROR window update frame: value=%d id=%d/%d/%d\n", value, id, sendid, recvid);
                        ErrProc(ERR_PROTOCOL_ERROR);
                        return 0;
                    }
                    WindowUpdateProc(id, value);
                    break;
                default:
                    LOGE("unkown http2 frame:%d\n", header->type);
                }
            }catch(...){
                Reset(id, ERR_INTERNAL_ERROR);
                return 0;
            }
            return length + sizeof(Http2_header);
        }
    }
}
示例#8
0
文件: http2.cpp 项目: choury/sproxy
void Http2Base::PingProc(const Http2_header* header) {
    if((header->flags & ACK_F) == 0) {
        Http2_header *header_back = (Http2_header *)p_memdup(header, sizeof(Http2_header) + get24(header->length));
        header_back->flags |= ACK_F;
        PushFrame(header_back);
    }
}