/* 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}); }
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); } }
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; }
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; }
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; }
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); } } }
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); } }