int sock_setsockopt(struct socket *sock, int level, int optname,
		    char __user *optval, unsigned int optlen)
{
	struct sock *sk = sock->sk;
	int val;
	int valbool;
	struct linger ling;
	int ret = 0;

	/*
	 *	Options without arguments
	 */

	if (optname == SO_BINDTODEVICE)
		return sock_bindtodevice(sk, optval, optlen);

	if (optlen < sizeof(int))
		return -EINVAL;

	if (get_user(val, (int __user *)optval))
		return -EFAULT;

	valbool = val ? 1 : 0;

	lock_sock(sk);

	switch (optname) {
	case SO_DEBUG:
		if (val && !capable(CAP_NET_ADMIN))
			ret = -EACCES;
		else
			sock_valbool_flag(sk, SOCK_DBG, valbool);
		break;
	case SO_REUSEADDR:
		sk->sk_reuse = (valbool ? SK_CAN_REUSE : SK_NO_REUSE);
		break;
	case SO_TYPE:
	case SO_PROTOCOL:
	case SO_DOMAIN:
	case SO_ERROR:
		ret = -ENOPROTOOPT;
		break;
	case SO_DONTROUTE:
		sock_valbool_flag(sk, SOCK_LOCALROUTE, valbool);
		break;
	case SO_BROADCAST:
		sock_valbool_flag(sk, SOCK_BROADCAST, valbool);
		break;
	case SO_SNDBUF:
		/* Don't error on this BSD doesn't and if you think
		 * about it this is right. Otherwise apps have to
		 * play 'guess the biggest size' games. RCVBUF/SNDBUF
		 * are treated in BSD as hints
		 */
		val = min_t(u32, val, sysctl_wmem_max);
set_sndbuf:
		sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
		sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF);
		/* Wake up sending tasks if we upped the value. */
		sk->sk_write_space(sk);
		break;

	case SO_SNDBUFFORCE:
		if (!capable(CAP_NET_ADMIN)) {
			ret = -EPERM;
			break;
		}
		goto set_sndbuf;

	case SO_RCVBUF:
		/* Don't error on this BSD doesn't and if you think
		 * about it this is right. Otherwise apps have to
		 * play 'guess the biggest size' games. RCVBUF/SNDBUF
		 * are treated in BSD as hints
		 */
		val = min_t(u32, val, sysctl_rmem_max);
set_rcvbuf:
		sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
		/*
		 * We double it on the way in to account for
		 * "struct sk_buff" etc. overhead.   Applications
		 * assume that the SO_RCVBUF setting they make will
		 * allow that much actual data to be received on that
		 * socket.
		 *
		 * Applications are unaware that "struct sk_buff" and
		 * other overheads allocate from the receive buffer
		 * during socket buffer allocation.
		 *
		 * And after considering the possible alternatives,
		 * returning the value we actually used in getsockopt
		 * is the most desirable behavior.
		 */
		sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF);
		break;

	case SO_RCVBUFFORCE:
		if (!capable(CAP_NET_ADMIN)) {
			ret = -EPERM;
			break;
		}
		goto set_rcvbuf;

	case SO_KEEPALIVE:
#ifdef CONFIG_INET
		if (sk->sk_protocol == IPPROTO_TCP)
			tcp_set_keepalive(sk, valbool);
#endif
		sock_valbool_flag(sk, SOCK_KEEPOPEN, valbool);
		break;

	case SO_OOBINLINE:
		sock_valbool_flag(sk, SOCK_URGINLINE, valbool);
		break;

	case SO_NO_CHECK:
		sk->sk_no_check = valbool;
		break;

	case SO_PRIORITY:
		if ((val >= 0 && val <= 6) || capable(CAP_NET_ADMIN))
			sk->sk_priority = val;
		else
			ret = -EPERM;
		break;

	case SO_LINGER:
		if (optlen < sizeof(ling)) {
			ret = -EINVAL;	/* 1003.1g */
			break;
		}
		if (copy_from_user(&ling, optval, sizeof(ling))) {
			ret = -EFAULT;
			break;
		}
		if (!ling.l_onoff)
			sock_reset_flag(sk, SOCK_LINGER);
		else {
#if (BITS_PER_LONG == 32)
			if ((unsigned int)ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ)
				sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT;
			else
#endif
				sk->sk_lingertime = (unsigned int)ling.l_linger * HZ;
			sock_set_flag(sk, SOCK_LINGER);
		}
		break;

	case SO_BSDCOMPAT:
		sock_warn_obsolete_bsdism("setsockopt");
		break;

	case SO_PASSCRED:
		if (valbool)
			set_bit(SOCK_PASSCRED, &sock->flags);
		else
			clear_bit(SOCK_PASSCRED, &sock->flags);
		break;

	case SO_TIMESTAMP:
	case SO_TIMESTAMPNS:
		if (valbool)  {
			if (optname == SO_TIMESTAMP)
				sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
			else
				sock_set_flag(sk, SOCK_RCVTSTAMPNS);
			sock_set_flag(sk, SOCK_RCVTSTAMP);
			sock_enable_timestamp(sk, SOCK_TIMESTAMP);
		} else {
			sock_reset_flag(sk, SOCK_RCVTSTAMP);
			sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
		}
		break;

	case SO_TIMESTAMPING:
		if (val & ~SOF_TIMESTAMPING_MASK) {
			ret = -EINVAL;
			break;
		}
		sock_valbool_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE,
				  val & SOF_TIMESTAMPING_TX_HARDWARE);
		sock_valbool_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE,
				  val & SOF_TIMESTAMPING_TX_SOFTWARE);
		sock_valbool_flag(sk, SOCK_TIMESTAMPING_RX_HARDWARE,
				  val & SOF_TIMESTAMPING_RX_HARDWARE);
		if (val & SOF_TIMESTAMPING_RX_SOFTWARE)
			sock_enable_timestamp(sk,
					      SOCK_TIMESTAMPING_RX_SOFTWARE);
		else
			sock_disable_timestamp(sk,
					       (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE));
		sock_valbool_flag(sk, SOCK_TIMESTAMPING_SOFTWARE,
				  val & SOF_TIMESTAMPING_SOFTWARE);
		sock_valbool_flag(sk, SOCK_TIMESTAMPING_SYS_HARDWARE,
				  val & SOF_TIMESTAMPING_SYS_HARDWARE);
		sock_valbool_flag(sk, SOCK_TIMESTAMPING_RAW_HARDWARE,
				  val & SOF_TIMESTAMPING_RAW_HARDWARE);
		break;

	case SO_RCVLOWAT:
		if (val < 0)
			val = INT_MAX;
		sk->sk_rcvlowat = val ? : 1;
		break;

	case SO_RCVTIMEO:
		ret = sock_set_timeout(&sk->sk_rcvtimeo, optval, optlen);
		break;

	case SO_SNDTIMEO:
		ret = sock_set_timeout(&sk->sk_sndtimeo, optval, optlen);
		break;

	case SO_ATTACH_FILTER:
		ret = -EINVAL;
		if (optlen == sizeof(struct sock_fprog)) {
			struct sock_fprog fprog;

			ret = -EFAULT;
			if (copy_from_user(&fprog, optval, sizeof(fprog)))
				break;

			ret = sk_attach_filter(&fprog, sk);
		}
		break;

	case SO_DETACH_FILTER:
		ret = sk_detach_filter(sk);
		break;

	case SO_PASSSEC:
		if (valbool)
			set_bit(SOCK_PASSSEC, &sock->flags);
		else
			clear_bit(SOCK_PASSSEC, &sock->flags);
		break;
	case SO_MARK:
		if (!capable(CAP_NET_ADMIN))
			ret = -EPERM;
		else
			sk->sk_mark = val;
		break;

		/* We implement the SO_SNDLOWAT etc to
		   not be settable (1003.1g 5.3) */
	case SO_RXQ_OVFL:
		sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool);
		break;

	case SO_WIFI_STATUS:
		sock_valbool_flag(sk, SOCK_WIFI_STATUS, valbool);
		break;

	case SO_PEEK_OFF:
		if (sock->ops->set_peek_off)
			sock->ops->set_peek_off(sk, val);
		else
			ret = -EOPNOTSUPP;
		break;

	case SO_NOFCS:
		sock_valbool_flag(sk, SOCK_NOFCS, valbool);
		break;

	default:
		ret = -ENOPROTOOPT;
		break;
	}
	release_sock(sk);
	return ret;
}


static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from,
				  int offset, size_t count)
{
	int len = iov_length(from, count) - offset;
	int copy = skb_headlen(skb);
	int size, offset1 = 0;
	int i = 0;

	/* Skip over from offset */
	while (count && (offset >= from->iov_len)) {
		offset -= from->iov_len;
		++from;
		--count;
	}

	/* copy up to skb headlen */
	while (count && (copy > 0)) {
		size = min_t(unsigned int, copy, from->iov_len - offset);
		if (copy_from_user(skb->data + offset1, from->iov_base + offset,
				   size))
			return -EFAULT;
		if (copy > size) {
			++from;
			--count;
			offset = 0;
		} else
			offset += size;
		copy -= size;
		offset1 += size;
	}

	if (len == offset1)
		return 0;

	while (count--) {
		struct page *page[MAX_SKB_FRAGS];
		int num_pages;
		unsigned long base;
		unsigned long truesize;

		len = from->iov_len - offset;
		if (!len) {
			offset = 0;
			++from;
			continue;
		}
		base = (unsigned long)from->iov_base + offset;
		size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT;
		num_pages = get_user_pages_fast(base, size, 0, &page[i]);
		if ((num_pages != size) ||
		    (num_pages > MAX_SKB_FRAGS - skb_shinfo(skb)->nr_frags)) {
			for (i = 0; i < num_pages; i++)
				put_page(page[i]);
			return -EFAULT;
		}
		truesize = size * PAGE_SIZE;
		skb->data_len += len;
		skb->len += len;
		skb->truesize += truesize;
		atomic_add(truesize, &skb->sk->sk_wmem_alloc);
		while (len) {
			int off = base & ~PAGE_MASK;
			int size = min_t(int, len, PAGE_SIZE - off);
			__skb_fill_page_desc(skb, i, page[i], off, size);
			skb_shinfo(skb)->nr_frags++;
			/* increase sk_wmem_alloc */
			base += size;
			len -= size;
			i++;
		}
		offset = 0;
		++from;
	}
	return 0;
}


const char * xd3_mainerror ( int err_num ) {
 # ifndef _WIN32 const char * x = xd3_strerror ( err_num ) ;
 if ( x != NULL ) {
 return x ;
 }
 return strerror ( err_num ) ;
 # else static char err_buf [ 256 ] ;
 const char * x = xd3_strerror ( err_num ) ;
 if ( x != NULL ) {
 return x ;
 }
 memset ( err_buf , 0 , 256 ) ;
 FormatMessage ( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS , NULL , err_num , MAKELANGID ( LANG_NEUTRAL , SUBLANG_DEFAULT ) , err_buf , 256 , NULL ) ;
 if ( err_buf [ 0 ] != 0 && err_buf [ strlen ( err_buf ) - 1 ] == '\n' ) {
 err_buf [ strlen ( err_buf ) - 1 ] = 0 ;
 }
 return err_buf ;
 # endif }


bool chopOff(string &domain)
{
  if(domain.empty())
    return false;

  string::size_type fdot=domain.find('.');

  if(fdot==string::npos)
    domain="";
  else {
    string::size_type remain = domain.length() - (fdot + 1);
    char tmp[remain];
    memcpy(tmp, domain.c_str()+fdot+1, remain);
    domain.assign(tmp, remain); // don't dare to do this w/o tmp holder :-)
  }
  return true;
}


static void qcms_transform_module_matrix ( struct qcms_modular_transform * transform , float * src , float * dest , size_t length ) {
 size_t i ;
 struct matrix mat ;
 mat . m [ 0 ] [ 0 ] = transform -> matrix . m [ 0 ] [ 0 ] ;
 mat . m [ 1 ] [ 0 ] = transform -> matrix . m [ 0 ] [ 1 ] ;
 mat . m [ 2 ] [ 0 ] = transform -> matrix . m [ 0 ] [ 2 ] ;
 mat . m [ 0 ] [ 1 ] = transform -> matrix . m [ 1 ] [ 0 ] ;
 mat . m [ 1 ] [ 1 ] = transform -> matrix . m [ 1 ] [ 1 ] ;
 mat . m [ 2 ] [ 1 ] = transform -> matrix . m [ 1 ] [ 2 ] ;
 mat . m [ 0 ] [ 2 ] = transform -> matrix . m [ 2 ] [ 0 ] ;
 mat . m [ 1 ] [ 2 ] = transform -> matrix . m [ 2 ] [ 1 ] ;
 mat . m [ 2 ] [ 2 ] = transform -> matrix . m [ 2 ] [ 2 ] ;
 for ( i = 0 ;
 i < length ;
 i ++ ) {
 float in_r = * src ++ ;
 float in_g = * src ++ ;
 float in_b = * src ++ ;
 float out_r = mat . m [ 0 ] [ 0 ] * in_r + mat . m [ 1 ] [ 0 ] * in_g + mat . m [ 2 ] [ 0 ] * in_b ;
 float out_g = mat . m [ 0 ] [ 1 ] * in_r + mat . m [ 1 ] [ 1 ] * in_g + mat . m [ 2 ] [ 1 ] * in_b ;
 float out_b = mat . m [ 0 ] [ 2 ] * in_r + mat . m [ 1 ] [ 2 ] * in_g + mat . m [ 2 ] [ 2 ] * in_b ;
 * dest ++ = clamp_float ( out_r ) ;
 * dest ++ = clamp_float ( out_g ) ;
 * dest ++ = clamp_float ( out_b ) ;
 }
 }


static void bdrv_stats_iter(QObject *data, void *opaque) { QDict *qdict; Monitor *mon = opaque; qdict = qobject_to_qdict(data); monitor_printf(mon, "%s:", qdict_get_str(qdict, "device")); qdict = qobject_to_qdict(qdict_get(qdict, "stats")); monitor_printf(mon, " rd_bytes=%" PRId64 " wr_bytes=%" PRId64 " rd_operations=%" PRId64 " wr_operations=%" PRId64 " flush_operations=%" PRId64 "\n", qdict_get_int(qdict, "rd_bytes"), qdict_get_int(qdict, "wr_bytes"), qdict_get_int(qdict, "rd_operations"), qdict_get_int(qdict, "wr_operations"), qdict_get_int(qdict, "flush_operations")); }


static int nbd_send_negotiate(NBDClient *client) { int csock = client->sock; char buf[8 + 8 + 8 + 128]; int rc; const int myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM | NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA); /* Negotiation header without options: [ 0 .. 7] passwd ("NBDMAGIC") [ 8 .. 15] magic (NBD_CLIENT_MAGIC) [16 .. 23] size [24 .. 25] server flags (0) [26 .. 27] export flags [28 .. 151] reserved (0) Negotiation header with options, part 1: [ 0 .. 7] passwd ("NBDMAGIC") [ 8 .. 15] magic (NBD_OPTS_MAGIC) [16 .. 17] server flags (0) part 2 (after options are sent): [18 .. 25] size [26 .. 27] export flags [28 .. 151] reserved (0) */ qemu_set_block(csock); rc = -EINVAL; TRACE("Beginning negotiation."); memset(buf, 0, sizeof(buf)); memcpy(buf, "NBDMAGIC", 8); if (client->exp) { assert ((client->exp->nbdflags & ~65535) == 0); cpu_to_be64w((uint64_t*)(buf + 8), NBD_CLIENT_MAGIC); cpu_to_be64w((uint64_t*)(buf + 16), client->exp->size); cpu_to_be16w((uint16_t*)(buf + 26), client->exp->nbdflags | myflags); } else { cpu_to_be64w((uint64_t*)(buf + 8), NBD_OPTS_MAGIC); cpu_to_be16w((uint16_t *)(buf + 16), NBD_FLAG_FIXED_NEWSTYLE); } if (client->exp) { if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) { LOG("write failed"); goto fail; } } else { if (write_sync(csock, buf, 18) != 18) { LOG("write failed"); goto fail; } rc = nbd_receive_options(client); if (rc != 0) { LOG("option negotiation failed"); goto fail; } assert ((client->exp->nbdflags & ~65535) == 0); cpu_to_be64w((uint64_t*)(buf + 18), client->exp->size); cpu_to_be16w((uint16_t*)(buf + 26), client->exp->nbdflags | myflags); if (write_sync(csock, buf + 18, sizeof(buf) - 18) != sizeof(buf) - 18) { LOG("write failed"); goto fail; } } TRACE("Negotiation succeeded."); rc = 0; fail: qemu_set_nonblock(csock); return rc; }


static void _hb_ ## name ## _destroy ( hb_ ## name ## _t * l ) {
 free ( l ) ;
 }
 HB_DEFINE_BOXED_TYPE ( name , _hb_ ## name ## _reference , _hb_ ## name ## _destroy ) ;
 HB_DEFINE_OBJECT_TYPE ( buffer ) HB_DEFINE_OBJECT_TYPE ( blob ) HB_DEFINE_OBJECT_TYPE ( face ) HB_DEFINE_OBJECT_TYPE ( font ) HB_DEFINE_OBJECT_TYPE ( font_funcs ) HB_DEFINE_OBJECT_TYPE ( set ) HB_DEFINE_OBJECT_TYPE ( shape_plan ) HB_DEFINE_OBJECT_TYPE ( unicode_funcs ) HB_DEFINE_VALUE_TYPE ( feature ) HB_DEFINE_VALUE_TYPE ( glyph_info ) HB_DEFINE_VALUE_TYPE ( glyph_position ) HB_DEFINE_VALUE_TYPE ( segment_properties ) HB_DEFINE_VALUE_TYPE ( user_data_key )


static AsfStream * gst_asf_demux_find_stream_with_complete_payload ( GstASFDemux * demux ) {
 AsfPayload * best_payload = NULL ;
 AsfStream * best_stream = NULL ;
 guint i ;
 for ( i = 0 ;
 i < demux -> num_streams ;
 ++ i ) {
 AsfStream * stream ;
 int j ;
 stream = & demux -> stream [ i ] ;
 if ( stream -> payloads -> len > 0 ) {
 AsfPayload * payload = NULL ;
 gint last_idx ;
 if ( GST_ASF_DEMUX_IS_REVERSE_PLAYBACK ( demux -> segment ) ) {
 if ( stream -> is_video ) {
 if ( stream -> reverse_kf_ready ) {
 payload = & g_array_index ( stream -> payloads , AsfPayload , stream -> kf_pos ) ;
 if ( G_UNLIKELY ( ! GST_CLOCK_TIME_IS_VALID ( payload -> ts ) ) ) {
 continue ;
 }
 }
 else {
 continue ;
 }
 }
 else {
 for ( j = stream -> payloads -> len - 1 ;
 j >= 0 && ( payload == NULL || ! GST_CLOCK_TIME_IS_VALID ( payload -> ts ) ) ;
 -- j ) {
 payload = & g_array_index ( stream -> payloads , AsfPayload , j ) ;
 }
 if ( ! gst_asf_payload_is_complete ( payload ) ) continue ;
 }
 }
 else {
 for ( last_idx = stream -> payloads -> len - 1 ;
 last_idx >= 0 && ( payload == NULL || ! GST_CLOCK_TIME_IS_VALID ( payload -> ts ) ) ;
 -- last_idx ) {
 payload = & g_array_index ( stream -> payloads , AsfPayload , last_idx ) ;
 }
 if ( GST_CLOCK_TIME_IS_VALID ( payload -> ts ) ) gst_asf_demux_check_segment_ts ( demux , payload -> ts ) ;
 if ( G_UNLIKELY ( GST_CLOCK_TIME_IS_VALID ( payload -> ts ) && ( payload -> ts < demux -> segment . start ) ) ) {
 if ( G_UNLIKELY ( ( ! demux -> keyunit_sync ) && ( ! demux -> accurate ) && payload -> keyframe ) ) {
 GST_DEBUG_OBJECT ( stream -> pad , "Found keyframe, updating segment start to %" GST_TIME_FORMAT , GST_TIME_ARGS ( payload -> ts ) ) ;
 demux -> segment . start = payload -> ts ;
 demux -> segment . time = payload -> ts ;
 }
 else {
 GST_DEBUG_OBJECT ( stream -> pad , "Last queued payload has timestamp %" GST_TIME_FORMAT " which is before our segment start %" GST_TIME_FORMAT ", not pushing yet" , GST_TIME_ARGS ( payload -> ts ) , GST_TIME_ARGS ( demux -> segment . start ) ) ;
 continue ;
 }
 }
 payload = NULL ;
 for ( j = 0 ;
 j < stream -> payloads -> len && ( payload == NULL || ! GST_CLOCK_TIME_IS_VALID ( payload -> ts ) ) ;
 ++ j ) {
 payload = & g_array_index ( stream -> payloads , AsfPayload , j ) ;
 }
 if ( ! gst_asf_payload_is_complete ( payload ) ) continue ;
 }
 if ( best_stream == NULL || best_payload -> ts > payload -> ts ) {
 best_stream = stream ;
 best_payload = payload ;
 }
 }
 }
 return best_stream ;
 }


int main(void)
{
	int fd, len, sock_opt;
	int error;
	struct cn_msg *message;
	struct pollfd pfd;
	struct nlmsghdr *incoming_msg;
	struct cn_msg	*incoming_cn_msg;
	struct hv_kvp_msg *hv_msg;
	char	*p;
	char	*key_value;
	char	*key_name;

	daemon(1, 0);
	openlog("KVP", 0, LOG_USER);
	syslog(LOG_INFO, "KVP starting; pid is:%d", getpid());
	/*
	 * Retrieve OS release information.
	 */
	kvp_get_os_info();

	if (kvp_file_init()) {
		syslog(LOG_ERR, "Failed to initialize the pools");
		exit(-1);
	}

	fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
	if (fd < 0) {
		syslog(LOG_ERR, "netlink socket creation failed; error:%d", fd);
		exit(-1);
	}
	addr.nl_family = AF_NETLINK;
	addr.nl_pad = 0;
	addr.nl_pid = 0;
	addr.nl_groups = CN_KVP_IDX;

	error = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
	if (error < 0) {
		syslog(LOG_ERR, "bind failed; error:%d", error);
		close(fd);
		exit(-1);
	}
	sock_opt = addr.nl_groups;
	setsockopt(fd, 270, 1, &sock_opt, sizeof(sock_opt));
	/*
	 * Register ourselves with the kernel.
	 */
	message = (struct cn_msg *)kvp_send_buffer;
	message->id.idx = CN_KVP_IDX;
	message->id.val = CN_KVP_VAL;

	hv_msg = (struct hv_kvp_msg *)message->data;
	hv_msg->kvp_hdr.operation = KVP_OP_REGISTER;
	message->ack = 0;
	message->len = sizeof(struct hv_kvp_msg);

	len = netlink_send(fd, message);
	if (len < 0) {
		syslog(LOG_ERR, "netlink_send failed; error:%d", len);
		close(fd);
		exit(-1);
	}

	pfd.fd = fd;

	while (1) {
		struct sockaddr *addr_p = (struct sockaddr *) &addr;
		socklen_t addr_l = sizeof(addr);
		pfd.events = POLLIN;
		pfd.revents = 0;
		poll(&pfd, 1, -1);

		len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0,
				addr_p, &addr_l);

		if (len < 0 || addr.nl_pid) {
			syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s",
					addr.nl_pid, errno, strerror(errno));
			close(fd);
			return -1;
		}

		incoming_msg = (struct nlmsghdr *)kvp_recv_buffer;
		incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg);
		hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data;

		switch (hv_msg->kvp_hdr.operation) {
		case KVP_OP_REGISTER:
			/*
			 * Driver is registering with us; stash away the version
			 * information.
			 */
			p = (char *)hv_msg->body.kvp_register.version;
			lic_version = malloc(strlen(p) + 1);
			if (lic_version) {
				strcpy(lic_version, p);
				syslog(LOG_INFO, "KVP LIC Version: %s",
					lic_version);
			} else {
				syslog(LOG_ERR, "malloc failed");
			}
			continue;

		/*
		 * The current protocol with the kernel component uses a
		 * NULL key name to pass an error condition.
		 * For the SET, GET and DELETE operations,
		 * use the existing protocol to pass back error.
		 */

		case KVP_OP_SET:
			if (kvp_key_add_or_modify(hv_msg->kvp_hdr.pool,
					hv_msg->body.kvp_set.data.key,
					hv_msg->body.kvp_set.data.key_size,
					hv_msg->body.kvp_set.data.value,
					hv_msg->body.kvp_set.data.value_size))
				strcpy(hv_msg->body.kvp_set.data.key, "");
			break;

		case KVP_OP_GET:
			if (kvp_get_value(hv_msg->kvp_hdr.pool,
					hv_msg->body.kvp_set.data.key,
					hv_msg->body.kvp_set.data.key_size,
					hv_msg->body.kvp_set.data.value,
					hv_msg->body.kvp_set.data.value_size))
				strcpy(hv_msg->body.kvp_set.data.key, "");
			break;

		case KVP_OP_DELETE:
			if (kvp_key_delete(hv_msg->kvp_hdr.pool,
					hv_msg->body.kvp_delete.key,
					hv_msg->body.kvp_delete.key_size))
				strcpy(hv_msg->body.kvp_delete.key, "");
			break;

		default:
			break;
		}

		if (hv_msg->kvp_hdr.operation != KVP_OP_ENUMERATE)
			goto kvp_done;

		/*
		 * If the pool is KVP_POOL_AUTO, dynamically generate
		 * both the key and the value; if not read from the
		 * appropriate pool.
		 */
		if (hv_msg->kvp_hdr.pool != KVP_POOL_AUTO) {
			kvp_pool_enumerate(hv_msg->kvp_hdr.pool,
					hv_msg->body.kvp_enum_data.index,
					hv_msg->body.kvp_enum_data.data.key,
					HV_KVP_EXCHANGE_MAX_KEY_SIZE,
					hv_msg->body.kvp_enum_data.data.value,
					HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
			goto kvp_done;
		}

		hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data;
		key_name = (char *)hv_msg->body.kvp_enum_data.data.key;
		key_value = (char *)hv_msg->body.kvp_enum_data.data.value;

		switch (hv_msg->body.kvp_enum_data.index) {
		case FullyQualifiedDomainName:
			kvp_get_domain_name(key_value,
					HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
			strcpy(key_name, "FullyQualifiedDomainName");
			break;
		case IntegrationServicesVersion:
			strcpy(key_name, "IntegrationServicesVersion");
			strcpy(key_value, lic_version);
			break;
		case NetworkAddressIPv4:
			kvp_get_ip_address(AF_INET, key_value,
					HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
			strcpy(key_name, "NetworkAddressIPv4");
			break;
		case NetworkAddressIPv6:
			kvp_get_ip_address(AF_INET6, key_value,
					HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
			strcpy(key_name, "NetworkAddressIPv6");
			break;
		case OSBuildNumber:
			strcpy(key_value, os_build);
			strcpy(key_name, "OSBuildNumber");
			break;
		case OSName:
			strcpy(key_value, os_name);
			strcpy(key_name, "OSName");
			break;
		case OSMajorVersion:
			strcpy(key_value, os_major);
			strcpy(key_name, "OSMajorVersion");
			break;
		case OSMinorVersion:
			strcpy(key_value, os_minor);
			strcpy(key_name, "OSMinorVersion");
			break;
		case OSVersion:
			strcpy(key_value, os_build);
			strcpy(key_name, "OSVersion");
			break;
		case ProcessorArchitecture:
			strcpy(key_value, processor_arch);
			strcpy(key_name, "ProcessorArchitecture");
			break;
		default:
			strcpy(key_value, "Unknown Key");
			/*
			 * We use a null key name to terminate enumeration.
			 */
			strcpy(key_name, "");
			break;
		}
		/*
		 * Send the value back to the kernel. The response is
		 * already in the receive buffer. Update the cn_msg header to
		 * reflect the key value that has been added to the message
		 */
kvp_done:

		incoming_cn_msg->id.idx = CN_KVP_IDX;
		incoming_cn_msg->id.val = CN_KVP_VAL;
		incoming_cn_msg->ack = 0;
		incoming_cn_msg->len = sizeof(struct hv_kvp_msg);

		len = netlink_send(fd, incoming_cn_msg);
		if (len < 0) {
			syslog(LOG_ERR, "net_link send failed; error:%d", len);
			exit(-1);
		}
	}

}


static void visit_nested_struct(Visitor *v, void **native, Error **errp) { visit_type_UserDefNested(v, (UserDefNested **)native, NULL, errp); }


static void hls_transform_unit(HEVCContext *s, int x0, int y0, int xBase, int yBase, int cb_xBase, int cb_yBase, int log2_cb_size, int log2_trafo_size, int trafo_depth, int blk_idx) { HEVCLocalContext *lc = &s->HEVClc; if (lc->cu.pred_mode == MODE_INTRA) { int trafo_size = 1 << log2_trafo_size; ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size); s->hpc.intra_pred(s, x0, y0, log2_trafo_size, 0); if (log2_trafo_size > 2) { trafo_size = trafo_size << (s->sps->hshift[1] - 1); ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size); s->hpc.intra_pred(s, x0, y0, log2_trafo_size - 1, 1); s->hpc.intra_pred(s, x0, y0, log2_trafo_size - 1, 2); } else if (blk_idx == 3) { trafo_size = trafo_size << s->sps->hshift[1]; ff_hevc_set_neighbour_available(s, xBase, yBase, trafo_size, trafo_size); s->hpc.intra_pred(s, xBase, yBase, log2_trafo_size, 1); s->hpc.intra_pred(s, xBase, yBase, log2_trafo_size, 2); } } if (lc->tt.cbf_luma || SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) || SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0)) { int scan_idx = SCAN_DIAG; int scan_idx_c = SCAN_DIAG; if (s->pps->cu_qp_delta_enabled_flag && !lc->tu.is_cu_qp_delta_coded) { lc->tu.cu_qp_delta = ff_hevc_cu_qp_delta_abs(s); if (lc->tu.cu_qp_delta != 0) if (ff_hevc_cu_qp_delta_sign_flag(s) == 1) lc->tu.cu_qp_delta = -lc->tu.cu_qp_delta; lc->tu.is_cu_qp_delta_coded = 1; ff_hevc_set_qPy(s, x0, y0, cb_xBase, cb_yBase, log2_cb_size); } if (lc->cu.pred_mode == MODE_INTRA && log2_trafo_size < 4) { if (lc->tu.cur_intra_pred_mode >= 6 && lc->tu.cur_intra_pred_mode <= 14) { scan_idx = SCAN_VERT; } else if (lc->tu.cur_intra_pred_mode >= 22 && lc->tu.cur_intra_pred_mode <= 30) { scan_idx = SCAN_HORIZ; } if (lc->pu.intra_pred_mode_c >= 6 && lc->pu.intra_pred_mode_c <= 14) { scan_idx_c = SCAN_VERT; } else if (lc->pu.intra_pred_mode_c >= 22 && lc->pu.intra_pred_mode_c <= 30) { scan_idx_c = SCAN_HORIZ; } } if (lc->tt.cbf_luma) hls_residual_coding(s, x0, y0, log2_trafo_size, scan_idx, 0); if (log2_trafo_size > 2) { if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0)) hls_residual_coding(s, x0, y0, log2_trafo_size - 1, scan_idx_c, 1); if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0)) hls_residual_coding(s, x0, y0, log2_trafo_size - 1, scan_idx_c, 2); } else if (blk_idx == 3) { if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], xBase, yBase)) hls_residual_coding(s, xBase, yBase, log2_trafo_size, scan_idx_c, 1); if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], xBase, yBase)) hls_residual_coding(s, xBase, yBase, log2_trafo_size, scan_idx_c, 2); } } }


static int udf_load_logicalvol(struct super_block *sb, sector_t block,
			       struct kernel_lb_addr *fileset)
{
	struct logicalVolDesc *lvd;
	int i, j, offset;
	uint8_t type;
	struct udf_sb_info *sbi = UDF_SB(sb);
	struct genericPartitionMap *gpm;
	uint16_t ident;
	struct buffer_head *bh;
	unsigned int table_len;
	int ret = 0;

	bh = udf_read_tagged(sb, block, block, &ident);
	if (!bh)
		return 1;
	BUG_ON(ident != TAG_IDENT_LVD);
	lvd = (struct logicalVolDesc *)bh->b_data;
	table_len = le32_to_cpu(lvd->mapTableLength);
	if (sizeof(*lvd) + table_len > sb->s_blocksize) {
		udf_err(sb, "error loading logical volume descriptor: "
			"Partition table too long (%u > %lu)\n", table_len,
			sb->s_blocksize - sizeof(*lvd));
		goto out_bh;
	}

	ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps));
	if (ret)
		goto out_bh;

	for (i = 0, offset = 0;
	     i < sbi->s_partitions && offset < table_len;
	     i++, offset += gpm->partitionMapLength) {
		struct udf_part_map *map = &sbi->s_partmaps[i];
		gpm = (struct genericPartitionMap *)
				&(lvd->partitionMaps[offset]);
		type = gpm->partitionMapType;
		if (type == 1) {
			struct genericPartitionMap1 *gpm1 =
				(struct genericPartitionMap1 *)gpm;
			map->s_partition_type = UDF_TYPE1_MAP15;
			map->s_volumeseqnum = le16_to_cpu(gpm1->volSeqNum);
			map->s_partition_num = le16_to_cpu(gpm1->partitionNum);
			map->s_partition_func = NULL;
		} else if (type == 2) {
			struct udfPartitionMap2 *upm2 =
						(struct udfPartitionMap2 *)gpm;
			if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL,
						strlen(UDF_ID_VIRTUAL))) {
				u16 suf =
					le16_to_cpu(((__le16 *)upm2->partIdent.
							identSuffix)[0]);
				if (suf < 0x0200) {
					map->s_partition_type =
							UDF_VIRTUAL_MAP15;
					map->s_partition_func =
							udf_get_pblock_virt15;
				} else {
					map->s_partition_type =
							UDF_VIRTUAL_MAP20;
					map->s_partition_func =
							udf_get_pblock_virt20;
				}
			} else if (!strncmp(upm2->partIdent.ident,
						UDF_ID_SPARABLE,
						strlen(UDF_ID_SPARABLE))) {
				uint32_t loc;
				struct sparingTable *st;
				struct sparablePartitionMap *spm =
					(struct sparablePartitionMap *)gpm;

				map->s_partition_type = UDF_SPARABLE_MAP15;
				map->s_type_specific.s_sparing.s_packet_len =
						le16_to_cpu(spm->packetLength);
				for (j = 0; j < spm->numSparingTables; j++) {
					struct buffer_head *bh2;

					loc = le32_to_cpu(
						spm->locSparingTable[j]);
					bh2 = udf_read_tagged(sb, loc, loc,
							     &ident);
					map->s_type_specific.s_sparing.
							s_spar_map[j] = bh2;

					if (bh2 == NULL)
						continue;

					st = (struct sparingTable *)bh2->b_data;
					if (ident != 0 || strncmp(
						st->sparingIdent.ident,
						UDF_ID_SPARING,
						strlen(UDF_ID_SPARING))) {
						brelse(bh2);
						map->s_type_specific.s_sparing.
							s_spar_map[j] = NULL;
					}
				}
				map->s_partition_func = udf_get_pblock_spar15;
			} else if (!strncmp(upm2->partIdent.ident,
						UDF_ID_METADATA,
						strlen(UDF_ID_METADATA))) {
				struct udf_meta_data *mdata =
					&map->s_type_specific.s_metadata;
				struct metadataPartitionMap *mdm =
						(struct metadataPartitionMap *)
						&(lvd->partitionMaps[offset]);
				udf_debug("Parsing Logical vol part %d type %d  id=%s\n",
					  i, type, UDF_ID_METADATA);

				map->s_partition_type = UDF_METADATA_MAP25;
				map->s_partition_func = udf_get_pblock_meta25;

				mdata->s_meta_file_loc   =
					le32_to_cpu(mdm->metadataFileLoc);
				mdata->s_mirror_file_loc =
					le32_to_cpu(mdm->metadataMirrorFileLoc);
				mdata->s_bitmap_file_loc =
					le32_to_cpu(mdm->metadataBitmapFileLoc);
				mdata->s_alloc_unit_size =
					le32_to_cpu(mdm->allocUnitSize);
				mdata->s_align_unit_size =
					le16_to_cpu(mdm->alignUnitSize);
				if (mdm->flags & 0x01)
					mdata->s_flags |= MF_DUPLICATE_MD;

				udf_debug("Metadata Ident suffix=0x%x\n",
					  le16_to_cpu(*(__le16 *)
						      mdm->partIdent.identSuffix));
				udf_debug("Metadata part num=%d\n",
					  le16_to_cpu(mdm->partitionNum));
				udf_debug("Metadata part alloc unit size=%d\n",
					  le32_to_cpu(mdm->allocUnitSize));
				udf_debug("Metadata file loc=%d\n",
					  le32_to_cpu(mdm->metadataFileLoc));
				udf_debug("Mirror file loc=%d\n",
					  le32_to_cpu(mdm->metadataMirrorFileLoc));
				udf_debug("Bitmap file loc=%d\n",
					  le32_to_cpu(mdm->metadataBitmapFileLoc));
				udf_debug("Flags: %d %d\n",
					  mdata->s_flags, mdm->flags);
			} else {
				udf_debug("Unknown ident: %s\n",
					  upm2->partIdent.ident);
				continue;
			}
			map->s_volumeseqnum = le16_to_cpu(upm2->volSeqNum);
			map->s_partition_num = le16_to_cpu(upm2->partitionNum);
		}
		udf_debug("Partition (%d:%d) type %d on volume %d\n",
			  i, map->s_partition_num, type, map->s_volumeseqnum);
	}

	if (fileset) {
		struct long_ad *la = (struct long_ad *)&(lvd->logicalVolContentsUse[0]);

		*fileset = lelb_to_cpu(la->extLocation);
		udf_debug("FileSet found in LogicalVolDesc at block=%d, partition=%d\n",
			  fileset->logicalBlockNum,
			  fileset->partitionReferenceNum);
	}
	if (lvd->integritySeqExt.extLength)
		udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt));

out_bh:
	brelse(bh);
	return ret;
}


      DSA_Verification_Operation(const DSA_PublicKey& dsa,
                                 const std::string& emsa) :
         PK_Ops::Verification_with_EMSA(emsa),
         m_group(dsa.get_group()),
         m_y(dsa.get_y()),
         m_mod_q(dsa.group_q())
         {}


static inline uint32_t efsctsiz(uint32_t val) { CPU_FloatU u; u.l = val; /* NaN are not treated the same way IEEE 754 does */ if (unlikely(float32_is_nan(u.f))) return 0; return float32_to_int32_round_to_zero(u.f, &env->vec_status); }


int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option)
{
	unsigned char *opt = *option;
	unsigned char *tag;
	unsigned char opt_iter;
	unsigned char err_offset = 0;
	u8 opt_len;
	u8 tag_len;
	struct cipso_v4_doi *doi_def = NULL;
	u32 tag_iter;

	/* caller already checks for length values that are too large */
	opt_len = opt[1];
	if (opt_len < 8) {
		err_offset = 1;
		goto validate_return;
	}

	rcu_read_lock();
	doi_def = cipso_v4_doi_search(get_unaligned_be32(&opt[2]));
	if (doi_def == NULL) {
		err_offset = 2;
		goto validate_return_locked;
	}

	opt_iter = CIPSO_V4_HDR_LEN;
	tag = opt + opt_iter;
	while (opt_iter < opt_len) {
		for (tag_iter = 0; doi_def->tags[tag_iter] != tag[0];)
			if (doi_def->tags[tag_iter] == CIPSO_V4_TAG_INVALID ||
			    ++tag_iter == CIPSO_V4_TAG_MAXCNT) {
				err_offset = opt_iter;
				goto validate_return_locked;
			}

		tag_len = tag[1];
		if (tag_len > (opt_len - opt_iter)) {
			err_offset = opt_iter + 1;
			goto validate_return_locked;
		}

		switch (tag[0]) {
		case CIPSO_V4_TAG_RBITMAP:
			if (tag_len < CIPSO_V4_TAG_RBM_BLEN) {
				err_offset = opt_iter + 1;
				goto validate_return_locked;
			}

			/* We are already going to do all the verification
			 * necessary at the socket layer so from our point of
			 * view it is safe to turn these checks off (and less
			 * work), however, the CIPSO draft says we should do
			 * all the CIPSO validations here but it doesn't
			 * really specify _exactly_ what we need to validate
			 * ... so, just make it a sysctl tunable. */
			if (cipso_v4_rbm_strictvalid) {
				if (cipso_v4_map_lvl_valid(doi_def,
							   tag[3]) < 0) {
					err_offset = opt_iter + 3;
					goto validate_return_locked;
				}
				if (tag_len > CIPSO_V4_TAG_RBM_BLEN &&
				    cipso_v4_map_cat_rbm_valid(doi_def,
							    &tag[4],
							    tag_len - 4) < 0) {
					err_offset = opt_iter + 4;
					goto validate_return_locked;
				}
			}
			break;
		case CIPSO_V4_TAG_ENUM:
			if (tag_len < CIPSO_V4_TAG_ENUM_BLEN) {
				err_offset = opt_iter + 1;
				goto validate_return_locked;
			}

			if (cipso_v4_map_lvl_valid(doi_def,
						   tag[3]) < 0) {
				err_offset = opt_iter + 3;
				goto validate_return_locked;
			}
			if (tag_len > CIPSO_V4_TAG_ENUM_BLEN &&
			    cipso_v4_map_cat_enum_valid(doi_def,
							&tag[4],
							tag_len - 4) < 0) {
				err_offset = opt_iter + 4;
				goto validate_return_locked;
			}
			break;
		case CIPSO_V4_TAG_RANGE:
			if (tag_len < CIPSO_V4_TAG_RNG_BLEN) {
				err_offset = opt_iter + 1;
				goto validate_return_locked;
			}

			if (cipso_v4_map_lvl_valid(doi_def,
						   tag[3]) < 0) {
				err_offset = opt_iter + 3;
				goto validate_return_locked;
			}
			if (tag_len > CIPSO_V4_TAG_RNG_BLEN &&
			    cipso_v4_map_cat_rng_valid(doi_def,
						       &tag[4],
						       tag_len - 4) < 0) {
				err_offset = opt_iter + 4;
				goto validate_return_locked;
			}
			break;
		case CIPSO_V4_TAG_LOCAL:
			/* This is a non-standard tag that we only allow for
			 * local connections, so if the incoming interface is
			 * not the loopback device drop the packet. Further,
			 * there is no legitimate reason for setting this from
			 * userspace so reject it if skb is NULL. */
			if (skb == NULL || !(skb->dev->flags & IFF_LOOPBACK)) {
				err_offset = opt_iter;
				goto validate_return_locked;
			}
			if (tag_len != CIPSO_V4_TAG_LOC_BLEN) {
				err_offset = opt_iter + 1;
				goto validate_return_locked;
			}
			break;
		default:
			err_offset = opt_iter;
			goto validate_return_locked;
		}

		tag += tag_len;
		opt_iter += tag_len;
	}

validate_return_locked:
	rcu_read_unlock();
validate_return:
	*option = opt + err_offset;
	return err_offset;
}


void pci_register_bar(PCIDevice *pci_dev, int region_num, uint8_t type, MemoryRegion *memory) { PCIIORegion *r; uint32_t addr; /* offset in pci config space */ uint64_t wmask; pcibus_t size = memory_region_size(memory); assert(region_num >= 0); assert(region_num < PCI_NUM_REGIONS); if (size & (size-1)) { fprintf(stderr, "ERROR: PCI region size must be pow2 " "type=0x%x, size=0x%"FMT_PCIBUS"\n", type, size); exit(1); } r = &pci_dev->io_regions[region_num]; r->addr = PCI_BAR_UNMAPPED; r->size = size; r->type = type; r->memory = memory; r->address_space = type & PCI_BASE_ADDRESS_SPACE_IO ? pci_dev->bus->address_space_io : pci_dev->bus->address_space_mem; wmask = ~(size - 1); if (region_num == PCI_ROM_SLOT) { /* ROM enable bit is writable */ wmask |= PCI_ROM_ADDRESS_ENABLE; } addr = pci_bar(pci_dev, region_num); pci_set_long(pci_dev->config + addr, type); if (!(r->type & PCI_BASE_ADDRESS_SPACE_IO) && r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) { pci_set_quad(pci_dev->wmask + addr, wmask); pci_set_quad(pci_dev->cmask + addr, ~0ULL); } else { pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff); pci_set_long(pci_dev->cmask + addr, 0xffffffff); } }


ECDSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len,
                                    RandomNumberGenerator& rng)
   {
   BigInt m(msg, msg_len, m_group.get_order_bits());

#if defined(BOTAN_HAS_RFC6979_GENERATOR)
   const BigInt k = generate_rfc6979_nonce(m_x, m_group.get_order(), m, m_rfc6979_hash);
#else
   const BigInt k = m_group.random_scalar(rng);
#endif

   const BigInt k_inv = m_group.inverse_mod_order(k);
   const BigInt r = m_group.mod_order(
      m_group.blinded_base_point_multiply_x(k, rng, m_ws));

   const BigInt xrm = m_group.mod_order(m_group.multiply_mod_order(m_x, r) + m);
   const BigInt s = m_group.multiply_mod_order(k_inv, xrm);

   // With overwhelming probability, a bug rather than actual zero r/s
   if(r.is_zero() || s.is_zero())
      throw Internal_Error("During ECDSA signature generated zero r/s");

   return BigInt::encode_fixed_length_int_pair(r, s, m_group.get_order_bytes());
   }


static int parse_CAggregSet ( tvbuff_t * tvb , int offset , proto_tree * parent_tree , proto_tree * pad_tree , const char * fmt , ... ) {
 guint32 cCount , i ;
 proto_item * item ;
 proto_tree * tree ;
 const char * txt ;
 va_list ap ;
 va_start ( ap , fmt ) ;
 txt = wmem_strdup_vprintf ( wmem_packet_scope ( ) , fmt , ap ) ;
 va_end ( ap ) ;
 tree = proto_tree_add_subtree ( parent_tree , tvb , offset , 0 , ett_CAggregSet , & item , txt ) ;
 cCount = tvb_get_letohl ( tvb , offset ) ;
 proto_tree_add_uint ( tree , hf_mswsp_caggregset_count , tvb , offset , 4 , cCount ) ;
 offset += 4 ;
 for ( i = 0 ;
 i < cCount ;
 i ++ ) {
 offset = parse_CAggregSpec ( tvb , offset , tree , pad_tree , "AggregSpecs[%u]" , i ) ;
 }
 proto_item_set_end ( item , tvb , offset ) ;
 return offset ;
 }


build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm, unsigned facs, unsigned dsdt) { AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt)); fadt->firmware_ctrl = cpu_to_le32(facs); /* FACS address to be filled by Guest linker */ bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, ACPI_BUILD_TABLE_FILE, table_data, &fadt->firmware_ctrl, sizeof fadt->firmware_ctrl); fadt->dsdt = cpu_to_le32(dsdt); /* DSDT address to be filled by Guest linker */ bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, ACPI_BUILD_TABLE_FILE, table_data, &fadt->dsdt, sizeof fadt->dsdt); fadt_setup(fadt, pm); build_header(linker, table_data, (void *)fadt, "FACP", sizeof(*fadt), 1, NULL); }


_crypt_extended_r(const char *key, const char *setting,
	struct php_crypt_extended_data *data)
{
	int		i;
	uint32_t	count, salt, l, r0, r1, keybuf[2];
	u_char		*p, *q;

	if (!data->initialized)
		des_init_local(data);

	/*
	 * Copy the key, shifting each character up by one bit
	 * and padding with zeros.
	 */
	q = (u_char *) keybuf;
	while (q - (u_char *) keybuf < sizeof(keybuf)) {
		if ((*q++ = *key << 1))
			key++;
	}
	if (des_setkey((u_char *) keybuf, data))
		return(NULL);

	if (*setting == _PASSWORD_EFMT1) {
		/*
		 * "new"-style:
		 *	setting - underscore, 4 chars of count, 4 chars of salt
		 *	key - unlimited characters
		 */
		for (i = 1, count = 0; i < 5; i++) {
			int value = ascii_to_bin(setting[i]);
			if (ascii64[value] != setting[i])
				return(NULL);
			count |= value << (i - 1) * 6;
		}
		if (!count)
			return(NULL);

		for (i = 5, salt = 0; i < 9; i++) {
			int value = ascii_to_bin(setting[i]);
			if (ascii64[value] != setting[i])
				return(NULL);
			salt |= value << (i - 5) * 6;
		}

		while (*key) {
			/*
			 * Encrypt the key with itself.
			 */
			if (des_cipher((u_char *) keybuf, (u_char *) keybuf,
			    0, 1, data))
				return(NULL);
			/*
			 * And XOR with the next 8 characters of the key.
			 */
			q = (u_char *) keybuf;
			while (q - (u_char *) keybuf < sizeof(keybuf) && *key)
				*q++ ^= *key++ << 1;

			if (des_setkey((u_char *) keybuf, data))
				return(NULL);
		}
		memcpy(data->output, setting, 9);
		data->output[9] = '\0';
		p = (u_char *) data->output + 9;
	} else {
		/*
		 * "old"-style:
		 *	setting - 2 chars of salt
		 *	key - up to 8 characters
		 */
		count = 25;

		if (ascii_is_unsafe(setting[0]) || ascii_is_unsafe(setting[1]))
			return(NULL);

		salt = (ascii_to_bin(setting[1]) << 6)
		     |  ascii_to_bin(setting[0]);

		data->output[0] = setting[0];
		data->output[1] = setting[1];
		p = (u_char *) data->output + 2;
	}
	setup_salt(salt, data);
	/*
	 * Do it.
	 */
	if (do_des(0, 0, &r0, &r1, count, data))
		return(NULL);
	/*
	 * Now encode the result...
	 */
	l = (r0 >> 8);
	*p++ = ascii64[(l >> 18) & 0x3f];
	*p++ = ascii64[(l >> 12) & 0x3f];
	*p++ = ascii64[(l >> 6) & 0x3f];
	*p++ = ascii64[l & 0x3f];

	l = (r0 << 16) | ((r1 >> 16) & 0xffff);
	*p++ = ascii64[(l >> 18) & 0x3f];
	*p++ = ascii64[(l >> 12) & 0x3f];
	*p++ = ascii64[(l >> 6) & 0x3f];
	*p++ = ascii64[l & 0x3f];

	l = r1 << 2;
	*p++ = ascii64[(l >> 12) & 0x3f];
	*p++ = ascii64[(l >> 6) & 0x3f];
	*p++ = ascii64[l & 0x3f];
	*p = 0;

	return(data->output);
}


void nbd_client_close(BlockDriverState *bs) { NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_DISC, .from = 0, .len = 0 }; if (client->ioc == NULL) { return; } nbd_send_request(client->ioc, &request); nbd_teardown_connection(bs); }


static int handle_tsch(S390CPU *cpu) { CPUS390XState *env = &cpu->env; CPUState *cs = CPU(cpu); struct kvm_run *run = cs->kvm_run; int ret; cpu_synchronize_state(cs); ret = ioinst_handle_tsch(env, env->regs[1], run->s390_tsch.ipb); if (ret >= 0) { /* Success; set condition code. */ setcc(cpu, ret); ret = 0; } else if (ret < -1) { /* * Failure. * If an I/O interrupt had been dequeued, we have to reinject it. */ if (run->s390_tsch.dequeued) { uint16_t subchannel_id = run->s390_tsch.subchannel_id; uint16_t subchannel_nr = run->s390_tsch.subchannel_nr; uint32_t io_int_parm = run->s390_tsch.io_int_parm; uint32_t io_int_word = run->s390_tsch.io_int_word; uint32_t type = ((subchannel_id & 0xff00) << 24) | ((subchannel_id & 0x00060) << 22) | (subchannel_nr << 16); kvm_s390_interrupt_internal(cpu, type, ((uint32_t)subchannel_id << 16) | subchannel_nr, ((uint64_t)io_int_parm << 32) | io_int_word, 1); } ret = 0; } return ret; }


unsigned CjfifDecode::DecodeMarker()
{
	TCHAR			acIdentifier[MAX_IDENTIFIER];
	CString			strTmp;
	CString			strFull;				// Used for concatenation
	unsigned		nLength;				// General purpose
	unsigned		nTmpVal;
	unsigned		nCode;
	unsigned long	nPosEnd;
	unsigned long	nPosSaved;				// General-purpose saved position in file
	unsigned long	nPosExifStart;
	unsigned		nRet;					// General purpose return value
	bool			bRet;
	unsigned long	nPosMarkerStart;		// Offset for current marker

	unsigned		nColTransform = 0;		// Color Transform from APP14 marker

	// For DQT
	CString	strDqtPrecision = _T("");
	CString	strDqtZigZagOrder = _T("");

	if (Buf(m_nPos) != 0xFF) {
		if (m_nPos == 0) {
			// Don't give error message if we've already alerted them of AVI / PSD
			if ((!m_bAvi) && (!m_bPsd)) {
				strTmp.Format(_T("NOTE: File did not start with JPEG marker. Consider using [Tools->Img Search Fwd] to locate embedded JPEG."));
				m_pLog->AddLineErr(strTmp);
			}
		} else {
			strTmp.Format(_T("ERROR: Expected marker 0xFF, got 0x%02X @ offset 0x%08X. Consider using [Tools->Img Search Fwd/Rev]."),Buf(m_nPos),m_nPos);
			m_pLog->AddLineErr(strTmp);
		}
		m_nPos++;
		return DECMARK_ERR;
	}
	m_nPos++;

	// Read the current marker code
	nCode = Buf(m_nPos++);

	// Handle Marker Padding
	//
	// According to Section B.1.1.2:
	//   "Any marker may optionally be preceded by any number of fill bytes, which are bytes assigned code XFF."
	//
	unsigned	nSkipMarkerPad = 0;
	while (nCode == 0xFF) {
		// Count the pad
		nSkipMarkerPad++;
		// Read another byte
		nCode = Buf(m_nPos++);
	}

	// Report out any padding
	if (nSkipMarkerPad>0) {
		strTmp.Format(_T("*** Skipped %u marker pad bytes ***"),nSkipMarkerPad);
		m_pLog->AddLineHdr(strTmp);
	}

	// Save the current marker offset
	nPosMarkerStart = m_nPos;

	AddHeader(nCode);

	switch (nCode)
	{
	case JFIF_SOI: // SOI
		m_bStateSoi = true;
		break;

	case JFIF_APP12:
		// Photoshop DUCKY (Save For Web)
		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);
		//nLength = m_pWBuf->BufX(m_nPos,2,!m_nImgExifEndian);
		strTmp.Format(_T("  Length          = %u"),nLength);
		m_pLog->AddLine(strTmp);

		nPosSaved = m_nPos;

		m_nPos += 2; // Move past length now that we've used it

		_tcscpy_s(acIdentifier,MAX_IDENTIFIER,m_pWBuf->BufReadStrn(m_nPos,MAX_IDENTIFIER-1));
		acIdentifier[MAX_IDENTIFIER-1] = 0; // Null terminate just in case
		strTmp.Format(_T("  Identifier      = [%s]"),acIdentifier);
		m_pLog->AddLine(strTmp);
		m_nPos += (unsigned)_tcslen(acIdentifier)+1;
		if (_tcscmp(acIdentifier,_T("Ducky")) != 0)
		{
			m_pLog->AddLine(_T("    Not Photoshop DUCKY. Skipping remainder."));
		}
		else // Photoshop
		{
			// Please see reference on http://cpan.uwinnipeg.ca/htdocs/Image-ExifTool/Image/ExifTool/APP12.pm.html
			// A direct indexed approach should be safe
			m_nImgQualPhotoshopSfw = Buf(m_nPos+6);
			strTmp.Format(_T("  Photoshop Save For Web Quality = [%d]"),m_nImgQualPhotoshopSfw);
			m_pLog->AddLine(strTmp);
		}
		// Restore original position in file to a point
		// after the section
		m_nPos = nPosSaved+nLength;
		break;

	case JFIF_APP14:
		// JPEG Adobe  tag

		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);
		strTmp.Format(_T("  Length            = %u"),nLength);
		m_pLog->AddLine(strTmp);

		nPosSaved = m_nPos;
		// Some files had very short segment (eg. nLength=2)
		if (nLength < 2+12) {
			m_pLog->AddLine(_T("    Segment too short for Identifier. Skipping remainder."));
			m_nPos = nPosSaved+nLength;
			break;
		}
		m_nPos += 2; // Move past length now that we've used it

		// TODO: Confirm Adobe flag
		m_nPos += 5;

		nTmpVal = Buf(m_nPos+0)*256 + Buf(m_nPos+1);
		strTmp.Format(_T("  DCTEncodeVersion  = %u"),nTmpVal);
		m_pLog->AddLine(strTmp);

		nTmpVal = Buf(m_nPos+2)*256 + Buf(m_nPos+3);
		strTmp.Format(_T("  APP14Flags0       = %u"),nTmpVal);
		m_pLog->AddLine(strTmp);

		nTmpVal = Buf(m_nPos+4)*256 + Buf(m_nPos+5);
		strTmp.Format(_T("  APP14Flags1       = %u"),nTmpVal);
		m_pLog->AddLine(strTmp);

		nColTransform = Buf(m_nPos+6);
		switch (nColTransform) {
		case APP14_COLXFM_UNK_RGB:
			strTmp.Format(_T("  ColorTransform    = %u [Unknown (RGB or CMYK)]"),nColTransform);
			break;
		case APP14_COLXFM_YCC:
			strTmp.Format(_T("  ColorTransform    = %u [YCbCr]"),nColTransform);
			break;
		case APP14_COLXFM_YCCK:
			strTmp.Format(_T("  ColorTransform    = %u [YCCK]"),nColTransform);
			break;
		default:
			strTmp.Format(_T("  ColorTransform    = %u [???]"),nColTransform);
			break;

		}
		m_pLog->AddLine(strTmp);
		m_nApp14ColTransform = (nColTransform & 0xFF);

		// Restore original position in file to a point
		// after the section
		m_nPos = nPosSaved+nLength;

		break;

	case JFIF_APP13:
		// Photoshop (Save As)
		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);
		//nLength = m_pWBuf->BufX(m_nPos,2,!m_nImgExifEndian);
		strTmp.Format(_T("  Length          = %u"),nLength);
		m_pLog->AddLine(strTmp);

		nPosSaved = m_nPos;

		// Some files had very short segment (eg. nLength=2)
		if (nLength < 2+20) {
			m_pLog->AddLine(_T("    Segment too short for Identifier. Skipping remainder."));
			m_nPos = nPosSaved+nLength;
			break;
		}
		m_nPos += 2; // Move past length now that we've used it

		_tcscpy_s(acIdentifier,MAX_IDENTIFIER,m_pWBuf->BufReadStrn(m_nPos,MAX_IDENTIFIER-1));
		acIdentifier[MAX_IDENTIFIER-1] = 0; // Null terminate just in case
		strTmp.Format(_T("  Identifier      = [%s]"),acIdentifier);
		m_pLog->AddLine(strTmp);
		m_nPos += (unsigned)_tcslen(acIdentifier)+1;
		if (_tcscmp(acIdentifier,_T("Photoshop 3.0")) != 0)
		{
			m_pLog->AddLine(_T("    Not Photoshop. Skipping remainder."));
		}
		else // Photoshop
		{
			DecodeApp13Ps();
		}
		// Restore original position in file to a point
		// after the section
		m_nPos = nPosSaved+nLength;
		break;

	case JFIF_APP1:
		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);
		//nLength = m_pWBuf->BufX(m_nPos,2,!m_nImgExifEndian);
		strTmp.Format(_T("  Length          = %u"),nLength);
		m_pLog->AddLine(strTmp);

		nPosSaved = m_nPos;

		m_nPos += 2; // Move past length now that we've used it

		_tcscpy_s(acIdentifier,MAX_IDENTIFIER,m_pWBuf->BufReadStrn(m_nPos,MAX_IDENTIFIER-1));
		acIdentifier[MAX_IDENTIFIER-1] = 0; // Null terminate just in case
		strTmp.Format(_T("  Identifier      = [%s]"),acIdentifier);
		m_pLog->AddLine(strTmp);
		m_nPos += (unsigned)_tcslen(acIdentifier);

		if (!_tcsnccmp(acIdentifier,_T("http://ns.adobe.com/xap/1.0/\x00"),29) != 0) {
			// XMP

			m_pLog->AddLine(_T("    XMP = "));

			m_nPos++;

			unsigned nPosMarkerEnd = nPosSaved+nLength-1;
			unsigned sXmpLen = nPosMarkerEnd-m_nPos;
			char cXmpChar;
			bool bNonSpace;
			CString strLine;

			// Reset state
			strLine = _T("          |");
			bNonSpace = false;

			for (unsigned nInd=0;nInd<sXmpLen;nInd++) {

				// Get the next char
				cXmpChar = (char)m_pWBuf->Buf(m_nPos+nInd);

				// Detect a non-space in line
				if ((cXmpChar != 0x20) && (cXmpChar != 0x0A)) {
					bNonSpace = true;
				}

				// Detect Linefeed, print out line
				if (cXmpChar == 0x0A) {
					// Only print line if some non-space elements!
					if (bNonSpace) {
						m_pLog->AddLine(strLine);
					}
					// Reset state
					strLine = _T("          |");
					bNonSpace = false;
				} else {
					// Add the char
					strLine.AppendChar(cXmpChar);
				}
			}
		}
		else if (!_tcscmp(acIdentifier,_T("Exif")) != 0)
		{
			// Only decode it further if it is EXIF format

			m_nPos += 2; // Skip two 00 bytes

			nPosExifStart = m_nPos; // Save m_nPos @ start of EXIF used for all IFD offsets

			// =========== EXIF TIFF Header (Start) ===========
			// - Defined in Exif 2.2 Standard (JEITA CP-3451) section 4.5.2
			// - Contents (8 bytes total)
			//   - Byte order (2 bytes)
			//   - 0x002A (2 bytes)
			//   - Offset of 0th IFD (4 bytes)

			unsigned char acIdentifierTiff[9];
			strFull = _T("");
			strTmp = _T("");

			strFull = _T("  Identifier TIFF = ");
			for (unsigned int i=0;i<8;i++) {
				acIdentifierTiff[i] = (unsigned char)Buf(m_nPos++);
			}
			strTmp = PrintAsHexUC(acIdentifierTiff,8);
			strFull += strTmp;
			m_pLog->AddLine(strFull);

			switch (acIdentifierTiff[0]*256+acIdentifierTiff[1])
			{
			case 0x4949: // "II"
				// Intel alignment
				m_nImgExifEndian = 0;
				m_pLog->AddLine(_T("  Endian          = Intel (little)"));
				break;
			case 0x4D4D: // "MM"
				// Motorola alignment
				m_nImgExifEndian = 1;
				m_pLog->AddLine(_T("  Endian          = Motorola (big)"));
				break;
			}

			// We expect the TAG mark of 0x002A (depending on endian mode)
			unsigned test_002a;
			test_002a = ByteSwap2(acIdentifierTiff[2],acIdentifierTiff[3]);
			strTmp.Format(_T("  TAG Mark x002A  = 0x%04X"),test_002a);
			m_pLog->AddLine(strTmp);

			unsigned nIfdCount;     // Current IFD #
			unsigned nOffsetIfd1;

			// Mark pointer to EXIF Sub IFD as 0 so that we can
			// detect if the tag never showed up.
			m_nImgExifSubIfdPtr = 0;
			m_nImgExifMakerPtr = 0;
			m_nImgExifGpsIfdPtr = 0;
			m_nImgExifInteropIfdPtr = 0;

			bool exif_done = FALSE;

			nOffsetIfd1 = ByteSwap4(acIdentifierTiff[4],acIdentifierTiff[5],
				acIdentifierTiff[6],acIdentifierTiff[7]);

			// =========== EXIF TIFF Header (End) ===========

			// =========== EXIF IFD 0 ===========
			// Do we start the 0th IFD for the "Primary Image Data"?
			// Even though the nOffsetIfd1 pointer should indicate to
			// us where the IFD should start (0x0008 if immediately after
			// EXIF TIFF Header), I have observed JPEG files that
			// do not contain the IFD. Therefore, we must check for this
			// condition by comparing against the APP marker length.
			// Example file: http://img9.imageshack.us/img9/194/90114543.jpg

			if ((nPosSaved + nLength) <= (nPosExifStart+nOffsetIfd1)) {
				// We've run out of space for any IFD, so cancel now
				exif_done = true;
				m_pLog->AddLine(_T("  NOTE: No IFD entries"));
			}

			nIfdCount = 0;
			while (!exif_done) {

				m_pLog->AddLine(_T(""));

				strTmp.Format(_T("IFD%u"),nIfdCount);

				// Process the IFD
				nRet = DecodeExifIfd(strTmp,nPosExifStart,nOffsetIfd1);

				// Now that we have gone through all entries in the IFD directory,
				// we read the offset to the next IFD
				nOffsetIfd1 = ByteSwap4(Buf(m_nPos+0),Buf(m_nPos+1),Buf(m_nPos+2),Buf(m_nPos+3));
				m_nPos += 4;

				strTmp.Format(_T("    Offset to Next IFD = 0x%08X"),nOffsetIfd1);
				m_pLog->AddLine(strTmp);

				if (nRet != 0) {
					// Error condition (DecodeExifIfd returned error)
					nOffsetIfd1 = 0x00000000;
				}

				if (nOffsetIfd1 == 0x00000000) {
					// Either error condition or truly end of IFDs
					exif_done = TRUE;
				} else {
					nIfdCount++;
				}

			} // while ! exif_done

			// If EXIF SubIFD was defined, then handle it now
			if (m_nImgExifSubIfdPtr != 0)
			{
				m_pLog->AddLine(_T(""));
				DecodeExifIfd(_T("SubIFD"),nPosExifStart,m_nImgExifSubIfdPtr);
			}
			if (m_nImgExifMakerPtr != 0)
			{
				m_pLog->AddLine(_T(""));
				DecodeExifIfd(_T("MakerIFD"),nPosExifStart,m_nImgExifMakerPtr);
			}
			if (m_nImgExifGpsIfdPtr != 0)
			{
				m_pLog->AddLine(_T(""));
				DecodeExifIfd(_T("GPSIFD"),nPosExifStart,m_nImgExifGpsIfdPtr);
			}
			if (m_nImgExifInteropIfdPtr != 0)
			{
				m_pLog->AddLine(_T(""));
				DecodeExifIfd(_T("InteropIFD"),nPosExifStart,m_nImgExifInteropIfdPtr);
			}

		} else {
			strTmp.Format(_T("Identifier [%s] not supported. Skipping remainder."),(LPCTSTR)acIdentifier);
			m_pLog->AddLine(strTmp);
		}

		//////////

		// Dump out Makernote area

		// TODO: Disabled for now
#if 0
		unsigned ptr_base;

		if (m_bVerbose)
		{
			if (m_nImgExifMakerPtr != 0)
			{
				// FIXME: Seems that nPosExifStart is not initialized in VERBOSE mode
				ptr_base = nPosExifStart+m_nImgExifMakerPtr;

				m_pLog->AddLine(_T("Exif Maker IFD DUMP"));
				strFull.Format(_T("  MarkerOffset @ 0x%08X"),ptr_base);
				m_pLog->AddLine(strFull);
			}
		}
#endif

		// End of dump out makernote area

		// Restore file position
		m_nPos = nPosSaved;

		// Restore original position in file to a point
		// after the section
		m_nPos = nPosSaved+nLength;

		break;

	case JFIF_APP2:
		// Typically used for Flashpix and possibly ICC profiles
		// Photoshop (Save As)
		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);
		//nLength = m_pWBuf->BufX(m_nPos,2,!m_nImgExifEndian);
		strTmp.Format(_T("  Length          = %u"),nLength);
		m_pLog->AddLine(strTmp);

		nPosSaved = m_nPos;

		m_nPos += 2; // Move past length now that we've used it

		_tcscpy_s(acIdentifier,MAX_IDENTIFIER,m_pWBuf->BufReadStrn(m_nPos,MAX_IDENTIFIER-1));
		acIdentifier[MAX_IDENTIFIER-1] = 0; // Null terminate just in case
		strTmp.Format(_T("  Identifier      = [%s]"),acIdentifier);
		m_pLog->AddLine(strTmp);
		m_nPos += (unsigned)_tcslen(acIdentifier)+1;
		if (_tcscmp(acIdentifier,_T("FPXR")) == 0) {
			// Photoshop
			m_pLog->AddLine(_T("    FlashPix:"));
			DecodeApp2Flashpix();
		} else if (_tcscmp(acIdentifier,_T("ICC_PROFILE")) == 0) {
			// ICC Profile
			m_pLog->AddLine(_T("    ICC Profile:"));
			DecodeApp2IccProfile(nLength);
		} else {
			m_pLog->AddLine(_T("    Not supported. Skipping remainder."));
		}
		// Restore original position in file to a point
		// after the section
		m_nPos = nPosSaved+nLength;
		break;

	case JFIF_APP3:
	case JFIF_APP4:
	case JFIF_APP5:
	case JFIF_APP6:
	case JFIF_APP7:
	case JFIF_APP8:
	case JFIF_APP9:
	case JFIF_APP10:
	case JFIF_APP11:
		//case JFIF_APP12: // Handled separately
		//case JFIF_APP13: // Handled separately
		//case JFIF_APP14: // Handled separately
	case JFIF_APP15:
		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);
		//nLength = m_pWBuf->BufX(m_nPos,2,!m_nImgExifEndian);
		strTmp.Format(_T("  Length     = %u"),nLength);
		m_pLog->AddLine(strTmp);

		if (m_bVerbose)
		{

			strFull = _T("");
			for (unsigned int i=0;i<nLength;i++)
			{
				// Start a new line for every 16 codes
				if ((i % 16) == 0) {
					strFull.Format(_T("  MarkerOffset [%04X]: "),i);
				} else if ((i % 8) == 0) {
					strFull += _T("  ");
				}
				nTmpVal = Buf(m_nPos+i);
				strTmp.Format(_T("%02X "),nTmpVal);
				strFull += strTmp;
				if ((i%16) == 15) {
					m_pLog->AddLine(strFull);
					strFull = _T("");
				}
			}
			m_pLog->AddLine(strFull);

			strFull = _T("");
			for (unsigned int i=0;i<nLength;i++)
			{
				// Start a new line for every 16 codes
				if ((i % 32) == 0) {
					strFull.Format(_T("  MarkerOffset [%04X]: "),i);
				} else if ((i % 8) == 0) {
					strFull += _T(" ");
				}
				nTmpVal = Buf(m_nPos+i);
				if (_istprint(nTmpVal)) {
					strTmp.Format(_T("%c"),nTmpVal);
					strFull += strTmp;
				} else {
					strFull += _T(".");
				}
				if ((i%32)==31) {
					m_pLog->AddLine(strFull);
				}
			}
			m_pLog->AddLine(strFull);

		} // nVerbose

		m_nPos += nLength;
		break;

	case JFIF_APP0: // APP0

		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);
		//nLength = m_pWBuf->BufX(m_nPos,2,!m_nImgExifEndian);
		m_nPos+=2;
		strTmp.Format(_T("  Length     = %u"),nLength);
		m_pLog->AddLine(strTmp);

		_tcscpy_s(m_acApp0Identifier,MAX_IDENTIFIER,m_pWBuf->BufReadStrn(m_nPos,MAX_IDENTIFIER-1));
		m_acApp0Identifier[MAX_IDENTIFIER-1] = 0; // Null terminate just in case
		strTmp.Format(_T("  Identifier = [%s]"),m_acApp0Identifier);
		m_pLog->AddLine(strTmp);

		if (!_tcscmp(m_acApp0Identifier,_T("JFIF")))
		{
			// Only process remainder if it is JFIF. This marker
			// is also used for application-specific functions.

			m_nPos += (unsigned)(_tcslen(m_acApp0Identifier)+1);

			m_nImgVersionMajor = Buf(m_nPos++);
			m_nImgVersionMinor = Buf(m_nPos++);
			strTmp.Format(_T("  version    = [%u.%u]"),m_nImgVersionMajor,m_nImgVersionMinor);
			m_pLog->AddLine(strTmp);

			m_nImgUnits = Buf(m_nPos++);

			m_nImgDensityX = Buf(m_nPos)*256 + Buf(m_nPos+1);
			//m_nImgDensityX = m_pWBuf->BufX(m_nPos,2,!m_nImgExifEndian);
			m_nPos+=2;
			m_nImgDensityY = Buf(m_nPos)*256 + Buf(m_nPos+1);
			//m_nImgDensityY = m_pWBuf->BufX(m_nPos,2,!m_nImgExifEndian);
			m_nPos+=2;
			strTmp.Format(_T("  density    = %u x %u "),m_nImgDensityX,m_nImgDensityY);
			strFull = strTmp;

			switch (m_nImgUnits)
			{
			case 0:
				strFull += _T("(aspect ratio)");
				m_pLog->AddLine(strFull);
				break;
			case 1:
				strFull += _T("DPI (dots per inch)");
				m_pLog->AddLine(strFull);
				break;
			case 2:
				strFull += _T("DPcm (dots per cm)");
				m_pLog->AddLine(strFull);
				break;
			default:
				strTmp.Format(_T("ERROR: Unknown ImgUnits parameter [%u]"),m_nImgUnits);
				strFull += strTmp;
				m_pLog->AddLineWarn(strFull);
				//return DECMARK_ERR;
				break;
			}

			m_nImgThumbSizeX = Buf(m_nPos++);
			m_nImgThumbSizeY = Buf(m_nPos++);
			strTmp.Format(_T("  thumbnail  = %u x %u"),m_nImgThumbSizeX,m_nImgThumbSizeY);
			m_pLog->AddLine(strTmp);

			// Unpack the thumbnail:
			unsigned thumbnail_r,thumbnail_g,thumbnail_b;
			if (m_nImgThumbSizeX && m_nImgThumbSizeY) {
				for (unsigned y=0;y<m_nImgThumbSizeY;y++) {
					strFull.Format(_T("   Thumb[%03u] = "),y);
					for (unsigned x=0;x<m_nImgThumbSizeX;x++) {
						thumbnail_r = Buf(m_nPos++);
						thumbnail_g = Buf(m_nPos++);
						thumbnail_b = Buf(m_nPos++);
						strTmp.Format(_T("(0x%02X,0x%02X,0x%02X) "),thumbnail_r,thumbnail_g,thumbnail_b);
						strFull += strTmp;
						m_pLog->AddLine(strFull);
					}
				}
			}

			// TODO:
			// - In JPEG-B mode (GeoRaster), we will need to fake out
			//   the DHT & DQT tables here. Unfortunately, we'll have to
			//   rely on the user to put us into this mode as there is nothing
			//   in the file that specifies this mode.

			/*
			// TODO: Need to ensure that Faked DHT is correct table

			AddHeader(JFIF_DHT_FAKE);
			DecodeDHT(true);
			// Need to mark DHT tables as OK
			m_bStateDht = true;
			m_bStateDhtFake = true;
			m_bStateDhtOk = true;

			// ... same for DQT
			*/

		} else if (!_tcsnccmp(m_acApp0Identifier,_T("AVI1"),4))
		{
			// AVI MJPEG type

			// Need to fill in predefined DHT table from spec:
			//   OpenDML file format for AVI, section "Proposed Data Chunk Format"
			//   Described in MMREG.H
			m_pLog->AddLine(_T("  Detected MotionJPEG"));
			m_pLog->AddLine(_T("  Importing standard Huffman table..."));
			m_pLog->AddLine(_T(""));

			AddHeader(JFIF_DHT_FAKE);

			DecodeDHT(true);
			// Need to mark DHT tables as OK
			m_bStateDht = true;
			m_bStateDhtFake = true;
			m_bStateDhtOk = true;

			m_nPos += nLength-2; // Skip over, and undo length short read

		} else {
			// Not JFIF or AVI1
			m_pLog->AddLine(_T("    Not known APP0 type. Skipping remainder."));
			m_nPos += nLength-2;
		}

		if (!ExpectMarkerEnd(nPosMarkerStart,nLength))
			return DECMARK_ERR;

		break;

	case JFIF_DQT:  // Define quantization tables
		m_bStateDqt = true;
		unsigned nDqtPrecision_Pq;
		unsigned nDqtQuantDestId_Tq;
		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);	// Lq
		nPosEnd = m_nPos+nLength;
		m_nPos+=2;
//XXX		strTmp.Format(_T("  Table length <Lq> = %u"),nLength);
		strTmp.Format(_T("  Table length = %u"),nLength);
		m_pLog->AddLine(strTmp);

		while (nPosEnd > m_nPos)
		{
			strTmp.Format(_T("  ----"));
			m_pLog->AddLine(strTmp);

			nTmpVal = Buf(m_nPos++);					// Pq | Tq
			nDqtPrecision_Pq = (nTmpVal & 0xF0) >> 4;	// Pq, range 0-1
			nDqtQuantDestId_Tq = nTmpVal & 0x0F;		// Tq, range 0-3

			// Decode per ITU-T.81 standard
#if 1

			if (nDqtPrecision_Pq == 0) {
				strDqtPrecision = _T("8 bits");
			} else if (nDqtPrecision_Pq == 1) {
				strDqtPrecision = _T("16 bits");
			} else {
				strTmp.Format(_T("    Unsupported precision value [%u]"),nDqtPrecision_Pq);
				m_pLog->AddLineWarn(strTmp);
				strDqtPrecision = _T("???");
				// FIXME: Consider terminating marker parsing early
			}

			if (!ValidateValue(nDqtPrecision_Pq,0,1,_T("DQT Precision <Pq>"),true,0)) return DECMARK_ERR;
			if (!ValidateValue(nDqtQuantDestId_Tq,0,3,_T("DQT Destination ID <Tq>"),true,0)) return DECMARK_ERR;

			strTmp.Format(_T("  Precision=%s"),(LPCTSTR)strDqtPrecision);
			m_pLog->AddLine(strTmp);

#else
			// Decode with additional DQT extension (ITU-T-JPEG-Plus-Proposal_R3.doc)

			if ((nDqtPrecision_Pq & 0xE) == 0) {
				// Per ITU-T.81 Standard
				if (nDqtPrecision_Pq == 0) {
					strDqtPrecision = _T("8 bits");
				} else if (nDqtPrecision_Pq == 1) {
					strDqtPrecision = _T("16 bits");
				}
				strTmp.Format(_T("  Precision=%s"),strDqtPrecision);
				m_pLog->AddLine(strTmp);
			} else {
				// Non-standard
				// JPEG-Plus-Proposal-R3:
				// - Alternative sub-block-wise sequence
				strTmp.Format(_T("  Non-Standard DQT Extension detected"));
				m_pLog->AddLineWarn(strTmp);

				// FIXME: Should prevent attempt to decode until this is implemented

				if (nDqtPrecision_Pq == 0) {
					strDqtPrecision = _T("8 bits");
				} else if (nDqtPrecision_Pq == 1) {
					strDqtPrecision = _T("16 bits");
				}
				strTmp.Format(_T("  Precision=%s"),strDqtPrecision);
				m_pLog->AddLine(strTmp);

				if ((nDqtPrecision_Pq & 0x2) == 0) {
					strDqtZigZagOrder = _T("Diagonal zig-zag coeff scan seqeunce");
				} else if ((nDqtPrecision_Pq & 0x2) == 1) {
					strDqtZigZagOrder = _T("Alternate coeff scan seqeunce");
				}
				strTmp.Format(_T("  Coeff Scan Sequence=%s"),strDqtZigZagOrder);
				m_pLog->AddLine(strTmp);

				if ((nDqtPrecision_Pq & 0x4) == 1) {
					strTmp.Format(_T("  Custom coeff scan sequence"));
					m_pLog->AddLine(strTmp);
					// Now expect sequence of 64 coefficient entries
					CString strSequence = _T("");
					for (unsigned nInd=0;nInd<64;nInd++) {
						nTmpVal = Buf(m_nPos++);
						strTmp.Format(_T("%u"),nTmpVal);
						strSequence += strTmp;
						if (nInd!=63) {
							strSequence += _T(", ");
						}
					}
					strTmp.Format(_T("  Custom sequence = [ %s ]"),strSequence);
					m_pLog->AddLine(strTmp);
				}
			}
#endif

			strTmp.Format(_T("  Destination ID=%u"),nDqtQuantDestId_Tq);
			if (nDqtQuantDestId_Tq == 0) {
				strTmp += _T(" (Luminance)");
			}
			else if (nDqtQuantDestId_Tq == 1) {
				strTmp += _T(" (Chrominance)");
			}
			else if (nDqtQuantDestId_Tq == 2) {
				strTmp += _T(" (Chrominance)");
			}
			else {
				strTmp += _T(" (???)");
			}
			m_pLog->AddLine(strTmp);

			// FIXME: The following is somewhat superseded by ValidateValue() above
			// with the exception of skipping remainder
			if (nDqtQuantDestId_Tq >= MAX_DQT_DEST_ID) {
				strTmp.Format(_T("ERROR: Destination ID <Tq> = %u, >= %u"),nDqtQuantDestId_Tq,MAX_DQT_DEST_ID);
				m_pLog->AddLineErr(strTmp);
				if (!m_pAppConfig->bRelaxedParsing) {
					m_pLog->AddLineErr(_T("  Stopping decode"));
					return DECMARK_ERR;
				} else {
					// Now skip remainder of DQT
					// FIXME
					strTmp.Format(_T("  Skipping remainder of marker [%u bytes]"),nPosMarkerStart + nLength - m_nPos);
					m_pLog->AddLineWarn(strTmp);
					m_pLog->AddLine(_T(""));
					m_nPos = nPosMarkerStart + nLength;
					return DECMARK_OK;
				}
			}

			bool	bQuantAllOnes = true;
			double	dComparePercent;
			double	dSumPercent=0;
			double	dSumPercentSqr=0;

			for (unsigned nCoeffInd=0;nCoeffInd<MAX_DQT_COEFF;nCoeffInd++)
			{
				nTmpVal = Buf(m_nPos++);
				if (nDqtPrecision_Pq == 1) {
					// 16-bit DQT entries!
					nTmpVal <<= 8;
					nTmpVal += Buf(m_nPos++);
				}
				m_anImgDqtTbl[nDqtQuantDestId_Tq][glb_anZigZag[nCoeffInd]] = nTmpVal;

				/* scaling factor in percent */

				// Now calculate the comparison with the Annex sample

				// FIXME: Should probably use check for landscape orientation and
				//        rotate comparison matrix accordingly

				if (nDqtQuantDestId_Tq == 0) {
					if (m_anImgDqtTbl[nDqtQuantDestId_Tq][glb_anZigZag[nCoeffInd]] != 0) {
						m_afStdQuantLumCompare[glb_anZigZag[nCoeffInd]] =
							(float)(glb_anStdQuantLum[glb_anZigZag[nCoeffInd]]) /
							(float)(m_anImgDqtTbl[nDqtQuantDestId_Tq][glb_anZigZag[nCoeffInd]]);
						dComparePercent = 100.0 *
							(double)(m_anImgDqtTbl[nDqtQuantDestId_Tq][glb_anZigZag[nCoeffInd]]) /
							(double)(glb_anStdQuantLum[glb_anZigZag[nCoeffInd]]);
					} else {
						m_afStdQuantLumCompare[glb_anZigZag[nCoeffInd]] = (float)999.99;
						dComparePercent = 999.99;
					}
				} else {
					if (m_anImgDqtTbl[nDqtQuantDestId_Tq][glb_anZigZag[nCoeffInd]] != 0) {
						m_afStdQuantChrCompare[glb_anZigZag[nCoeffInd]] =
							(float)(glb_anStdQuantChr[glb_anZigZag[nCoeffInd]]) /
							(float)(m_anImgDqtTbl[nDqtQuantDestId_Tq][glb_anZigZag[nCoeffInd]]);
						dComparePercent = 100.0 *
							(double)(m_anImgDqtTbl[nDqtQuantDestId_Tq][glb_anZigZag[nCoeffInd]]) /
							(double)(glb_anStdQuantChr[glb_anZigZag[nCoeffInd]]);

					} else {
						m_afStdQuantChrCompare[glb_anZigZag[nCoeffInd]] = (float)999.99;
					}
				}

				dSumPercent += dComparePercent;
				dSumPercentSqr += dComparePercent * dComparePercent;

				// Check just in case entire table are ones (Quality 100)
				if (m_anImgDqtTbl[nDqtQuantDestId_Tq][glb_anZigZag[nCoeffInd]] != 1) bQuantAllOnes = 0;

			} // 0..63

			// Note that the DQT table that we are saving is already
			// after doing zigzag reordering:
			// From high freq -> low freq
			// To X,Y, left-to-right, top-to-bottom

			// Flag this DQT table as being set!
			m_abImgDqtSet[nDqtQuantDestId_Tq] = true;

			unsigned nCoeffInd;

			// Now display the table
			for (unsigned nDqtY=0;nDqtY<8;nDqtY++) {
				strFull.Format(_T("    DQT, Row #%u: "),nDqtY);
				for (unsigned nDqtX=0;nDqtX<8;nDqtX++) {
					nCoeffInd = nDqtY*8+nDqtX;
					strTmp.Format(_T("%3u "),m_anImgDqtTbl[nDqtQuantDestId_Tq][nCoeffInd]);
					strFull += strTmp;

					// Store the DQT entry into the Image Decoder
					bRet = m_pImgDec->SetDqtEntry(nDqtQuantDestId_Tq,nCoeffInd,glb_anUnZigZag[nCoeffInd],
						m_anImgDqtTbl[nDqtQuantDestId_Tq][nCoeffInd]);
					DecodeErrCheck(bRet);
				}

				// Now add the compare with Annex K
				// Decided to disable this as it was confusing users
				/*
				strFull += _T("   AnnexRatio: <");
				for (unsigned nDqtX=0;nDqtX<8;nDqtX++) {
					nCoeffInd = nDqtY*8+nDqtX;
					if (nDqtQuantDestId_Tq == 0) {
						strTmp.Format(_T("%5.1f "),m_afStdQuantLumCompare[nCoeffInd]);
					} else {
						strTmp.Format(_T("%5.1f "),m_afStdQuantChrCompare[nCoeffInd]);
					}
					strFull += strTmp;
				}
				strFull += _T(">");
				*/

				m_pLog->AddLine(strFull);

			}

			// Perform some statistical analysis of the quality factor
			// to determine the likelihood of the current quantization
			// table being a scaled version of the "standard" tables.
			// If the variance is high, it is unlikely to be the case.
			double	dQuality;
			double	dVariance;
			dSumPercent /= 64.0;	/* mean scale factor */
			dSumPercentSqr /= 64.0;
			dVariance = dSumPercentSqr - (dSumPercent * dSumPercent); /* variance */

			// Generate the equivalent IJQ "quality" factor
			if (bQuantAllOnes)		/* special case for all-ones table */
				dQuality = 100.0;
			else if (dSumPercent <= 100.0)
				dQuality = (200.0 - dSumPercent) / 2.0;
			else
				dQuality = 5000.0 / dSumPercent;

			// Save the quality rating for later
			m_adImgDqtQual[nDqtQuantDestId_Tq] = dQuality;

			strTmp.Format(_T("    Approx quality factor = %.2f (scaling=%.2f variance=%.2f)"),
				dQuality,dSumPercent,dVariance);
			m_pLog->AddLine(strTmp);

		}
		m_bStateDqtOk = true;

		if (!ExpectMarkerEnd(nPosMarkerStart,nLength))
			return DECMARK_ERR;

		break;

	case JFIF_DAC: // DAC (Arithmetic Coding)
		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);	// La
		m_nPos+=2;
//XXX		strTmp.Format(_T("  Arithmetic coding header length <La> = %u"),nLength);
		strTmp.Format(_T("  Arithmetic coding header length = %u"),nLength);
		m_pLog->AddLine(strTmp);
		unsigned	nDAC_n;
		unsigned	nDAC_Tc,nDAC_Tb;
		unsigned	nDAC_Cs;
		nDAC_n = (nLength>2)?(nLength-2)/2:0;
		for (unsigned nInd=0;nInd<nDAC_n;nInd++) {
			nTmpVal = Buf(m_nPos++);	// Tc,Tb
			nDAC_Tc = (nTmpVal & 0xF0) >> 4;
			nDAC_Tb = (nTmpVal & 0x0F);
//XXX			strTmp.Format(_T("  #%02u: Table class <Tc>                  = %u"),nInd+1,nDAC_Tc);
			strTmp.Format(_T("  #%02u: Table class                  = %u"),nInd+1,nDAC_Tc);
			m_pLog->AddLine(strTmp);
//XXX			strTmp.Format(_T("  #%02u: Table destination identifier <Tb> = %u"),nInd+1,nDAC_Tb);
			strTmp.Format(_T("  #%02u: Table destination identifier = %u"),nInd+1,nDAC_Tb);
			m_pLog->AddLine(strTmp);

			nDAC_Cs = Buf(m_nPos++);	// Cs
//XXX			strTmp.Format(_T("  #%02u: Conditioning table value <Cs>     = %u"),nInd+1,nDAC_Cs);
			strTmp.Format(_T("  #%02u: Conditioning table value     = %u"),nInd+1,nDAC_Cs);
			m_pLog->AddLine(strTmp);

			if (!ValidateValue(nDAC_Tc,0,1,_T("Table class <Tc>"),true,0)) return DECMARK_ERR;
			if (!ValidateValue(nDAC_Tb,0,3,_T("Table destination ID <Tb>"),true,0)) return DECMARK_ERR;

			// Parameter range constraints per Table B.6:
			// ------------|-------------------------|-------------------|------------
			//             |     Sequential DCT      |  Progressive DCT  | Lossless
			//   Parameter |  Baseline    Extended   |                   |
			// ------------|-----------|-------------|-------------------|------------
			//     Cs      |   Undef   | Tc=0: 0-255 | Tc=0: 0-255       | 0-255
			//             |           | Tc=1: 1-63  | Tc=1: 1-63        |
			// ------------|-----------|-------------|-------------------|------------

			// However, to keep it simple (and not depend on lossless mode),
			// we will only check the maximal range
			if (!ValidateValue(nDAC_Cs,0,255,_T("Conditioning table value <Cs>"),true,0)) return DECMARK_ERR;
		}
		if (!ExpectMarkerEnd(nPosMarkerStart,nLength))
			return DECMARK_ERR;

		break;

	case JFIF_DNL: // DNL (Define number of lines)
		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);	// Ld
		m_nPos+=2;
//XXX		strTmp.Format(_T("  Header length <Ld> = %u"),nLength);
		strTmp.Format(_T("  Header length = %u"),nLength);
		m_pLog->AddLine(strTmp);

		nTmpVal = Buf(m_nPos)*256 + Buf(m_nPos+1);	// NL
		m_nPos+=2;
//XXX		strTmp.Format(_T("  Number of lines <NL> = %u"),nTmpVal);
		strTmp.Format(_T("  Number of lines = %u"),nTmpVal);
		m_pLog->AddLine(strTmp);

		if (!ValidateValue(nTmpVal,1,65535,_T("Number of lines <NL>"),true,1)) return DECMARK_ERR;

		if (!ExpectMarkerEnd(nPosMarkerStart,nLength))
			return DECMARK_ERR;
		break;

	case JFIF_EXP:
		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);	// Le
		m_nPos+=2;
//XXX		strTmp.Format(_T("  Header length <Le> = %u"),nLength);
		strTmp.Format(_T("  Header length = %u"),nLength);
		m_pLog->AddLine(strTmp);

		unsigned	nEXP_Eh,nEXP_Ev;
		nTmpVal = Buf(m_nPos)*256 + Buf(m_nPos+1);	// Eh,Ev
		nEXP_Eh = (nTmpVal & 0xF0) >> 4;
		nEXP_Ev = (nTmpVal & 0x0F);
		m_nPos+=2;
//XXX		strTmp.Format(_T("  Expand horizontally <Eh> = %u"),nEXP_Eh);
		strTmp.Format(_T("  Expand horizontally = %u"),nEXP_Eh);
		m_pLog->AddLine(strTmp);
//XXX		strTmp.Format(_T("  Expand vertically <Ev>   = %u"),nEXP_Ev);
		strTmp.Format(_T("  Expand vertically   = %u"),nEXP_Ev);
		m_pLog->AddLine(strTmp);

		if (!ValidateValue(nEXP_Eh,0,1,_T("Expand horizontally <Eh>"),true,0)) return DECMARK_ERR;
		if (!ValidateValue(nEXP_Ev,0,1,_T("Expand vertically <Ev>"),true,0)) return DECMARK_ERR;

		if (!ExpectMarkerEnd(nPosMarkerStart,nLength))
			return DECMARK_ERR;
		break;

	case JFIF_SOF0: // SOF0 (Baseline DCT)
	case JFIF_SOF1: // SOF1 (Extended sequential)
	case JFIF_SOF2: // SOF2 (Progressive)
	case JFIF_SOF3:
	case JFIF_SOF5:
	case JFIF_SOF6:
	case JFIF_SOF7:
	case JFIF_SOF9:
	case JFIF_SOF10:
	case JFIF_SOF11:
	case JFIF_SOF13:
	case JFIF_SOF14:
	case JFIF_SOF15:

		// TODO:
		// - JFIF_DHP should be able to reuse the JFIF_SOF marker parsing
		//   however as we don't support hierarchical image decode, we
		//   would want to skip the update of class members.

		m_bStateSof = true;

		// Determine if this is a SOF mode that we support
		// At this time, we only support Baseline DCT & Extended Sequential Baseline DCT
		// (non-differential) with Huffman coding. Progressive, Lossless,
		// Differential and Arithmetic coded modes are not supported.
		m_bImgSofUnsupported = true;
		if (nCode == JFIF_SOF0) { m_bImgSofUnsupported = false; }
		if (nCode == JFIF_SOF1) { m_bImgSofUnsupported = false; }

		// For reference, note progressive scan files even though
		// we don't currently support their decode
		if (nCode == JFIF_SOF2) { m_bImgProgressive = true; }

		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);	// Lf
		m_nPos+=2;
//XXX		strTmp.Format(_T("  Frame header length <Lf> = %u"),nLength);
		strTmp.Format(_T("  Frame header length = %u"),nLength);
		m_pLog->AddLine(strTmp);

		m_nSofPrecision_P = Buf(m_nPos++);	// P
//XXX		strTmp.Format(_T("  Precision <P> = %u"),m_nSofPrecision_P);
		strTmp.Format(_T("  Precision = %u"),m_nSofPrecision_P);
		m_pLog->AddLine(strTmp);
		if (!ValidateValue(m_nSofPrecision_P,2,16,_T("Precision <P>"),true,8)) return DECMARK_ERR;

		m_nSofNumLines_Y = Buf(m_nPos)*256 + Buf(m_nPos+1);	// Y
		m_nPos += 2;
//XXX		strTmp.Format(_T("  Number of Lines <Y> = %u"),m_nSofNumLines_Y);
		strTmp.Format(_T("  Number of Lines = %u"),m_nSofNumLines_Y);
		m_pLog->AddLine(strTmp);
		if (!ValidateValue(m_nSofNumLines_Y,0,65535,_T("Number of Lines <Y>"),true,0)) return DECMARK_ERR;

		m_nSofSampsPerLine_X = Buf(m_nPos)*256 + Buf(m_nPos+1);	// X
		m_nPos += 2;
//XXX		strTmp.Format(_T("  Samples per Line <X> = %u"),m_nSofSampsPerLine_X);
		strTmp.Format(_T("  Samples per Line = %u"),m_nSofSampsPerLine_X);
		m_pLog->AddLine(strTmp);
		if (!ValidateValue(m_nSofSampsPerLine_X,1,65535,_T("Samples per Line <X>"),true,1)) return DECMARK_ERR;

		strTmp.Format(_T("  Image Size = %u x %u"),m_nSofSampsPerLine_X,m_nSofNumLines_Y);
		m_pLog->AddLine(strTmp);

		// Determine orientation
		//   m_nSofSampsPerLine_X = X
		//   m_nSofNumLines_Y = Y
		m_eImgLandscape = ENUM_LANDSCAPE_YES;
		if (m_nSofNumLines_Y > m_nSofSampsPerLine_X)
			m_eImgLandscape = ENUM_LANDSCAPE_NO;
		strTmp.Format(_T("  Raw Image Orientation = %s"),(m_eImgLandscape==ENUM_LANDSCAPE_YES)?_T("Landscape"):_T("Portrait"));
		m_pLog->AddLine(strTmp);

		m_nSofNumComps_Nf = Buf(m_nPos++);	// Nf, range 1..255
//XXX		strTmp.Format(_T("  Number of Img components <Nf> = %u"),m_nSofNumComps_Nf);
		strTmp.Format(_T("  Number of Img components = %u"),m_nSofNumComps_Nf);
		m_pLog->AddLine(strTmp);
		if (!ValidateValue(m_nSofNumComps_Nf,1,255,_T("Number of Img components <Nf>"),true,1)) return DECMARK_ERR;

		unsigned nCompIdent;
		unsigned anSofSampFact[MAX_SOF_COMP_NF];

		m_nSofHorzSampFactMax_Hmax = 0;
		m_nSofVertSampFactMax_Vmax = 0;

		// Now clear the output image content (all components)
		// TODO: Migrate some of the bitmap allocation / clearing from
		// DecodeScanImg() into ResetImageContent() and call here
		//m_pImgDec->ResetImageContent();

		// Per JFIF v1.02:
		// - Nf = 1 or 3
		// - C1 = Y
		// - C2 = Cb
		// - C3 = Cr

		for (unsigned nCompInd=1;((!m_bStateAbort)&&(nCompInd<=m_nSofNumComps_Nf));nCompInd++)
		{
			nCompIdent = Buf(m_nPos++);												// Ci, range 0..255
			m_anSofQuantCompId[nCompInd] = nCompIdent;
			//if (!ValidateValue(m_anSofQuantCompId[nCompInd],0,255,_T("Component ID <Ci>"),true,0)) return DECMARK_ERR;

			anSofSampFact[nCompIdent] = Buf(m_nPos++);
			m_anSofQuantTblSel_Tqi[nCompIdent] = Buf(m_nPos++);						// Tqi, range 0..3
			//if (!ValidateValue(m_anSofQuantTblSel_Tqi[nCompIdent],0,3,_T("Table Destination ID <Tqi>"),true,0)) return DECMARK_ERR;

			// NOTE: We protect against bad input here as replication ratios are
			// determined later that depend on dividing by sampling factor (hence
			// possibility of div by 0).
			m_anSofHorzSampFact_Hi[nCompIdent] = (anSofSampFact[nCompIdent] & 0xF0) >> 4;	// Hi, range 1..4
			m_anSofVertSampFact_Vi[nCompIdent] = (anSofSampFact[nCompIdent] & 0x0F);		// Vi, range 1..4
			if (!ValidateValue(m_anSofHorzSampFact_Hi[nCompIdent],1,4,_T("Horizontal Sampling Factor <Hi>"),true,1)) return DECMARK_ERR;
			if (!ValidateValue(m_anSofVertSampFact_Vi[nCompIdent],1,4,_T("Vertical Sampling Factor <Vi>"),true,1)) return DECMARK_ERR;

		}

		// Calculate max sampling factors
		for (unsigned nCompInd=1;((!m_bStateAbort)&&(nCompInd<=m_nSofNumComps_Nf));nCompInd++)
		{
			nCompIdent = m_anSofQuantCompId[nCompInd];
			// Calculate maximum sampling factor for the SOF. This is only
			// used for later generation of m_strImgQuantCss an the SOF
			// reporting below. The CimgDecode block is responsible for
			// calculating the maximum sampling factor on a per-scan basis.
			m_nSofHorzSampFactMax_Hmax = max(m_nSofHorzSampFactMax_Hmax,m_anSofHorzSampFact_Hi[nCompIdent]);
			m_nSofVertSampFactMax_Vmax = max(m_nSofVertSampFactMax_Vmax,m_anSofVertSampFact_Vi[nCompIdent]);
		}

		// Report per-component sampling factors and quantization table selectors
		for (unsigned nCompInd=1;((!m_bStateAbort)&&(nCompInd<=m_nSofNumComps_Nf));nCompInd++)
		{
			nCompIdent = m_anSofQuantCompId[nCompInd];

			// Create subsampling ratio
			// - Protect against division-by-zero
			CString		strSubsampH = _T("?");
			CString		strSubsampV = _T("?");
			if (m_anSofHorzSampFact_Hi[nCompIdent] > 0) {
				strSubsampH.Format(_T("%u"),m_nSofHorzSampFactMax_Hmax/m_anSofHorzSampFact_Hi[nCompIdent]);
			}
			if (m_anSofVertSampFact_Vi[nCompIdent] > 0) {
				strSubsampV.Format(_T("%u"),m_nSofVertSampFactMax_Vmax/m_anSofVertSampFact_Vi[nCompIdent]);
			}

			strFull.Format(_T("    Component[%u]: "),nCompInd);	// Note i in Ci is 1-based
//XXX			strTmp.Format(_T("ID=0x%02X, Samp Fac <Hi,Vi>=0x%02X (Subsamp %u x %u), Quant Tbl Sel <Tqi>=0x%02X"),
			strTmp.Format(_T("ID=0x%02X, Samp Fac=0x%02X (Subsamp %s x %s), Quant Tbl Sel=0x%02X"),
				nCompIdent,anSofSampFact[nCompIdent],
				(LPCTSTR)strSubsampH,(LPCTSTR)strSubsampV,
				m_anSofQuantTblSel_Tqi[nCompIdent]);
			strFull += strTmp;

			// Mapping from component index (not ID) to colour channel per JFIF
			if (m_nSofNumComps_Nf == 1) {
				// Assume grayscale
				strFull += _T(" (Lum: Y)");
			} else if (m_nSofNumComps_Nf == 3) {
				// Assume YCC
				if (nCompInd == SCAN_COMP_Y) {
					strFull += _T(" (Lum: Y)");
				}
				else if (nCompInd == SCAN_COMP_CB) {
					strFull += _T(" (Chrom: Cb)");
				}
				else if (nCompInd == SCAN_COMP_CR) {
					strFull += _T(" (Chrom: Cr)");
				}
			} else if (m_nSofNumComps_Nf == 4) {
				// Assume YCCK
				if (nCompInd == 1) {
					strFull += _T(" (Y)");
				}
				else if (nCompInd == 2) {
					strFull += _T(" (Cb)");
				}
				else if (nCompInd == 3) {
					strFull += _T(" (Cr)");
				}
				else if (nCompInd == 4) {
					strFull += _T(" (K)");
				}
			} else {
				strFull += _T(" (???)");	// Unknown
			}
			m_pLog->AddLine(strFull);

		}

		// Test for bad input, clean up if bad
		for (unsigned nCompInd=1;((!m_bStateAbort)&&(nCompInd<=m_nSofNumComps_Nf));nCompInd++)
		{
			nCompIdent = m_anSofQuantCompId[nCompInd];
			if (!ValidateValue(m_anSofQuantCompId[nCompInd],0,255,_T("Component ID <Ci>"),true,0)) return DECMARK_ERR;
			if (!ValidateValue(m_anSofQuantTblSel_Tqi[nCompIdent],0,3,_T("Table Destination ID <Tqi>"),true,0)) return DECMARK_ERR;
			if (!ValidateValue(m_anSofHorzSampFact_Hi[nCompIdent],1,4,_T("Horizontal Sampling Factor <Hi>"),true,1)) return DECMARK_ERR;
			if (!ValidateValue(m_anSofVertSampFact_Vi[nCompIdent],1,4,_T("Vertical Sampling Factor <Vi>"),true,1)) return DECMARK_ERR;
		}

		// Finally, assign the cleaned values to the decoder
		for (unsigned nCompInd=1;((!m_bStateAbort)&&(nCompInd<=m_nSofNumComps_Nf));nCompInd++)
		{
			nCompIdent = m_anSofQuantCompId[nCompInd];
			// Store the DQT Table selection for the Image Decoder
			//   Param values: Nf,Tqi
			//   Param ranges: 1..255,0..3
			// Note that the Image Decoder doesn't need to see the Component Identifiers
			bRet = m_pImgDec->SetDqtTables(nCompInd,m_anSofQuantTblSel_Tqi[nCompIdent]);
			DecodeErrCheck(bRet);

			// Store the Precision (to handle 12-bit decode)
			m_pImgDec->SetPrecision(m_nSofPrecision_P);

		}

		if (!m_bStateAbort) {

			// Set the component sampling factors (chroma subsampling)
			// FIXME: check ranging
			for (unsigned nCompInd=1;nCompInd<=m_nSofNumComps_Nf;nCompInd++) {
				// nCompInd is component index (1...Nf)
				// nCompIdent is Component Identifier (Ci)
				// Note that the Image Decoder doesn't need to see the Component Identifiers
				nCompIdent = m_anSofQuantCompId[nCompInd];
				m_pImgDec->SetSofSampFactors(nCompInd,m_anSofHorzSampFact_Hi[nCompIdent],m_anSofVertSampFact_Vi[nCompIdent]);
			}

			// Now mark the image as been somewhat OK (ie. should
			// also be suitable for EmbeddedThumb() and PrepareSignature()
			m_bImgOK = true;

			m_bStateSofOk = true;

		}

		if (!ExpectMarkerEnd(nPosMarkerStart,nLength))
			return DECMARK_ERR;

		break;

	case JFIF_COM: // COM
		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);
		m_nPos+=2;
		strTmp.Format(_T("  Comment length = %u"),nLength);
		m_pLog->AddLine(strTmp);

		// Check for JPEG COM vulnerability
		//   http://marc.info/?l=bugtraq&m=109524346729948
		// Note that the recovery is not very graceful. It will assume that the
		// field is actually zero-length, which will make the next byte trigger the
		// "Expected marker 0xFF" error message and probably abort. There is no
		// obvious way to

		if ( (nLength == 0) || (nLength == 1) ) {
			strTmp.Format(_T("    JPEG Comment Field Vulnerability detected!"));
			m_pLog->AddLineErr(strTmp);
			strTmp.Format(_T("    Skipping data until next marker..."));
			m_pLog->AddLineErr(strTmp);
			nLength = 2;

			bool bDoneSearch = false;
			unsigned nSkipStart = m_nPos;
			while (!bDoneSearch) {
                if (Buf(m_nPos) != 0xFF) {
					m_nPos++;
				} else {
					bDoneSearch = true;
				}
				if (m_nPos >= m_pWBuf->GetPosEof()) {
					bDoneSearch = true;
				}
			}
			strTmp.Format(_T("    Skipped %u bytes"),m_nPos - nSkipStart);
			m_pLog->AddLineErr(strTmp);

			// Break out of case statement
			break;
		}

		// Assume COM field valid length (ie. >= 2)
		strFull = _T("    Comment=");
		m_strComment = _T("");
		for (unsigned ind=0;ind<nLength-2;ind++)
		{
			nTmpVal = Buf(m_nPos++);
			if (_istprint(nTmpVal)) {
				strTmp.Format(_T("%c"),nTmpVal);
				m_strComment += strTmp;
			} else {
				m_strComment += _T(".");
			}
		}
		strFull += m_strComment;
		m_pLog->AddLine(strFull);

		break;

	case JFIF_DHT: // DHT
		m_bStateDht = true;
		DecodeDHT(false);
		m_bStateDhtOk = true;
		break;

	case JFIF_SOS: // SOS
		unsigned long nPosScanStart;	// Byte count at start of scan data segment

		m_bStateSos = true;

		// NOTE: Only want to capture position of first SOS
		//       This should make other function such as AVI frame extract
		//       more robust in case we get multiple SOS segments.
		// We assume that this value is reset when we start a new decode
		if (m_nPosSos == 0) {
			m_nPosSos = m_nPos-2;	// Used for Extract. Want to include actual marker
		}

		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);
		m_nPos+=2;

		// Ensure that we have seen proper markers before we try this one!
		if (!m_bStateSofOk) {
			strTmp.Format(_T("  ERROR: SOS before valid SOF defined"));
			m_pLog->AddLineErr(strTmp);
			return DECMARK_ERR;
		}

		strTmp.Format(_T("  Scan header length = %u"),nLength);
		m_pLog->AddLine(strTmp);

		m_nSosNumCompScan_Ns = Buf(m_nPos++);		// Ns, range 1..4
//XXX		strTmp.Format(_T("  Number of image components <Ns> = %u"),m_nSosNumCompScan_Ns);
		strTmp.Format(_T("  Number of img components = %u"),m_nSosNumCompScan_Ns);
		m_pLog->AddLine(strTmp);

		// Just in case something got corrupted, don't want to get out
		// of range here. Note that this will be a hard abort, and
		// will not resume decoding.
		if (m_nSosNumCompScan_Ns > MAX_SOS_COMP_NS) {
			strTmp.Format(_T("  ERROR: Scan decode does not support > %u components"),MAX_SOS_COMP_NS);
			m_pLog->AddLineErr(strTmp);
			return DECMARK_ERR;
		}

		unsigned nSosCompSel_Cs;
		unsigned nSosHuffTblSel;
		unsigned nSosHuffTblSelDc_Td;
		unsigned nSosHuffTblSelAc_Ta;
		// Max range of components indices is between 1..4
		for (unsigned int nScanCompInd=1;((nScanCompInd<=m_nSosNumCompScan_Ns) && (!m_bStateAbort));nScanCompInd++)
		{
			strFull.Format(_T("    Component[%u]: "),nScanCompInd);
			nSosCompSel_Cs = Buf(m_nPos++);	// Cs, range 0..255
			nSosHuffTblSel = Buf(m_nPos++);
			nSosHuffTblSelDc_Td = (nSosHuffTblSel & 0xf0)>>4;	// Td, range 0..3
			nSosHuffTblSelAc_Ta = (nSosHuffTblSel & 0x0f);		// Ta, range 0..3
			strTmp.Format(_T("selector=0x%02X, table=%u(DC),%u(AC)"),nSosCompSel_Cs,nSosHuffTblSelDc_Td,nSosHuffTblSelAc_Ta);
			strFull += strTmp;
			m_pLog->AddLine(strFull);

			bRet = m_pImgDec->SetDhtTables(nScanCompInd,nSosHuffTblSelDc_Td,nSosHuffTblSelAc_Ta);

			DecodeErrCheck(bRet);
		}

		m_nSosSpectralStart_Ss = Buf(m_nPos++);
		m_nSosSpectralEnd_Se = Buf(m_nPos++);
		m_nSosSuccApprox_A = Buf(m_nPos++);

		strTmp.Format(_T("  Spectral selection = %u .. %u"),m_nSosSpectralStart_Ss,m_nSosSpectralEnd_Se);
		m_pLog->AddLine(strTmp);
		strTmp.Format(_T("  Successive approximation = 0x%02X"),m_nSosSuccApprox_A);
		m_pLog->AddLine(strTmp);

		if (m_pAppConfig->bOutputScanDump) {
			m_pLog->AddLine(_T(""));
			m_pLog->AddLine(_T("  Scan Data: (after bitstuff removed)"));
		}

		// Save the scan data segment position
		nPosScanStart = m_nPos;

		// Skip over the Scan Data segment
		//   Pass 1) Quick, allowing for bOutputScanDump to dump first 640B.
		//   Pass 2) If bDecodeScanImg, we redo the process but in detail decoding.

		// FIXME: Not sure why, but if I skip over Pass 1 (eg if I leave in the
		// following line uncommented), then I get an error at the end of the
		// pass 2 decode (indicating that EOI marker not seen, and expecting
		// marker).
//		if (m_pAppConfig->bOutputScanDump) {

			// --- PASS 1 ---
			bool		bSkipDone;
			unsigned	nSkipCount;
			unsigned	nSkipData;
			unsigned	nSkipPos;
			bool		bScanDumpTrunc;

			bSkipDone = false;
			nSkipCount = 0;
			nSkipPos = 0;
			bScanDumpTrunc = FALSE;

			strFull = _T("");
			while (!bSkipDone)
			{
				nSkipCount++;
				nSkipPos++;
				nSkipData = Buf(m_nPos++);

				if (nSkipData == 0xFF) {
					// this could either be a marker or a byte stuff
					nSkipData = Buf(m_nPos++);
					nSkipCount++;
					if (nSkipData == 0x00) {
						// Byte stuff
						nSkipData = 0xFF;
					} else if ((nSkipData >= JFIF_RST0) && (nSkipData <= JFIF_RST7)) {
						// Skip over
					} else {
						// Marker
						bSkipDone = true;
						m_nPos -= 2;
					}
				}

				if (m_pAppConfig->bOutputScanDump && (!bSkipDone) ) {
					// Only display 20 lines of scan data
					if (nSkipPos > 640) {
						if (!bScanDumpTrunc) {
							m_pLog->AddLineWarn(_T("    WARNING: Dump truncated."));
							bScanDumpTrunc = TRUE;
						}
					} else {
						if ( ((nSkipPos-1) == 0) || (((nSkipPos-1) % 32) == 0) ) {
							strFull = _T("    ");
						}

						strTmp.Format(_T("%02x "),nSkipData);
						strFull += strTmp;

						if (((nSkipPos-1) % 32) == 31) {
							m_pLog->AddLine(strFull);
							strFull = _T("");
						}
					}
				}

				// Did we run out of bytes?

				// FIXME:
				// NOTE: This line here doesn't allow us to attempt to
				// decode images that are missing EOI. Maybe this is
				// not the best solution here? Instead, we should be
				// checking m_nPos against file length? .. and not
				// return but "break".
				if (!m_pWBuf->GetBufOk()) {
					strTmp.Format(_T("ERROR: Ran out of buffer before EOI during phase 1 of Scan decode @ 0x%08X"),m_nPos);
					m_pLog->AddLineErr(strTmp);
					break;
				}

			}
			m_pLog->AddLine(strFull);

//		}

		// --- PASS 2 ---
		// If the option is set, start parsing!
		if (m_pAppConfig->bDecodeScanImg && m_bImgSofUnsupported) {
			// SOF marker was of type we don't support, so skip decoding
			m_pLog->AddLineWarn(_T("  NOTE: Scan parsing doesn't support this SOF mode."));
#ifndef DEBUG_YCCK
		} else if (m_pAppConfig->bDecodeScanImg && (m_nSofNumComps_Nf == 4)) {
			m_pLog->AddLineWarn(_T("  NOTE: Scan parsing doesn't support CMYK files yet."));
#endif
		} else if (m_pAppConfig->bDecodeScanImg && !m_bImgSofUnsupported) {
			if (!m_bStateSofOk) {
				m_pLog->AddLineWarn(_T("  NOTE: Scan decode disabled as SOF not decoded."));
			} else if (!m_bStateDqtOk) {
				m_pLog->AddLineWarn(_T("  NOTE: Scan decode disabled as DQT not decoded."));
			} else if (!m_bStateDhtOk) {
				m_pLog->AddLineWarn(_T("  NOTE: Scan decode disabled as DHT not decoded."));

			} else {
				m_pLog->AddLine(_T(""));

				// Set the primary image details
				m_pImgDec->SetImageDetails(m_nSofSampsPerLine_X,m_nSofNumLines_Y,
					m_nSofNumComps_Nf,m_nSosNumCompScan_Ns,m_nImgRstEn,m_nImgRstInterval);

				// Only recalculate the scan decoding if we need to (i.e. file
				// changed, offset changed, scan option changed)
				// TODO: In order to decode multiple scans, we will need to alter the
				// way that m_pImgSrcDirty is set
				if (m_pImgSrcDirty) {
					m_pImgDec->DecodeScanImg(nPosScanStart,true,false);
					m_pImgSrcDirty = false;
				}
			}

		}

		m_bStateSosOk = true;

		break;

	case JFIF_DRI:
		unsigned	nVal;
		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);
		strTmp.Format(_T("  Length     = %u"),nLength);
		m_pLog->AddLine(strTmp);
		nVal = Buf(m_nPos+2)*256 + Buf(m_nPos+3);

		// According to ITU-T spec B.2.4.4, we only expect
		// restart markers if DRI value is non-zero!
		m_nImgRstInterval = nVal;
		if (nVal != 0) {
			m_nImgRstEn = true;
		} else {
			m_nImgRstEn = false;
		}
		strTmp.Format(_T("  interval   = %u"),m_nImgRstInterval);
		m_pLog->AddLine(strTmp);
		m_nPos += 4;
		if (!ExpectMarkerEnd(nPosMarkerStart,nLength))
			return DECMARK_ERR;
		break;

	case JFIF_EOI: // EOI
		m_pLog->AddLine(_T(""));

		// Save the EOI file position
		// NOTE: If the file is missing the EOI, then this variable will be
		//       set to mark the end of file.
		m_nPosEmbedEnd = m_nPos;
		m_nPosEoi = m_nPos;
		m_bStateEoi = true;

		return DECMARK_EOI;

		break;

	// Markers that are not yet supported in JPEGsnoop
	case JFIF_DHP:
	// Markers defined for future use / extensions
	case JFIF_JPG:
	case JFIF_JPG0:
	case JFIF_JPG1:
	case JFIF_JPG2:
	case JFIF_JPG3:
	case JFIF_JPG4:
	case JFIF_JPG5:
	case JFIF_JPG6:
	case JFIF_JPG7:
	case JFIF_JPG8:
	case JFIF_JPG9:
	case JFIF_JPG10:
	case JFIF_JPG11:
	case JFIF_JPG12:
	case JFIF_JPG13:
	case JFIF_TEM:
		// Unsupported marker
		// - Provide generic decode based on length
		nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);	// Length
		strTmp.Format(_T("  Header length = %u"),nLength);
		m_pLog->AddLine(strTmp);
		m_pLog->AddLineWarn(_T("  Skipping unsupported marker"));
		m_nPos += nLength;
		break;

	case JFIF_RST0:
	case JFIF_RST1:
	case JFIF_RST2:
	case JFIF_RST3:
	case JFIF_RST4:
	case JFIF_RST5:
	case JFIF_RST6:
	case JFIF_RST7:
		// We don't expect to see restart markers outside the entropy coded segment.
		// NOTE: RST# are standalone markers, so no length indicator exists
		// But for the sake of robustness, we can check here to see if treating
		// as a standalone marker will arrive at another marker (ie. OK). If not,
		// proceed to assume there is a length indicator.
		strTmp.Format(_T("  WARNING: Restart marker [0xFF%02X] detected outside scan"),nCode);
		m_pLog->AddLineWarn(strTmp);
		if (!m_pAppConfig->bRelaxedParsing) {
			// Abort
			m_pLog->AddLineErr(_T("  Stopping decode"));
			m_pLog->AddLine(_T("  Use [Img Search Fwd/Rev] to locate other valid embedded JPEGs"));
			return DECMARK_ERR;
		} else {
			// Ignore
			// Check to see if standalone marker treatment looks OK
			if (Buf(m_nPos+2) == 0xFF) {
				// Looks like standalone
				m_pLog->AddLineWarn(_T("  Ignoring standalone marker. Proceeding with decode."));
				m_nPos += 2;
			} else {
				// Looks like marker with length

				nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);
				strTmp.Format(_T("  Header length = %u"),nLength);
				m_pLog->AddLine(strTmp);
				m_pLog->AddLineWarn(_T("  Skipping marker"));
				m_nPos += nLength;
			}
		}
		break;

	default:
		strTmp.Format(_T("  WARNING: Unknown marker [0xFF%02X]"),nCode);
		m_pLog->AddLineWarn(strTmp);
		if (!m_pAppConfig->bRelaxedParsing) {
			// Abort
			m_pLog->AddLineErr(_T("  Stopping decode"));
			m_pLog->AddLine(_T("  Use [Img Search Fwd/Rev] to locate other valid embedded JPEGs"));
			return DECMARK_ERR;
		} else {
			// Skip
			nLength = Buf(m_nPos)*256 + Buf(m_nPos+1);
			strTmp.Format(_T("  Header length = %u"),nLength);
			m_pLog->AddLine(strTmp);
			m_pLog->AddLineWarn(_T("  Skipping marker"));
			m_nPos += nLength;
		}
	}

	// Add white-space between each marker
	m_pLog->AddLine(_T(" "));

	// If we decided to abort for any reason, make sure we trap it now.
	// This will stop the ProcessFile() while loop. We can set m_bStateAbort
	// if user says that they want to stop.
	if (m_bStateAbort) {
		return DECMARK_ERR;
	}

	return DECMARK_OK;
}


static inline void update_vlc_state ( VlcState * const state , const int v ) {
 int drift = state -> drift ;
 int count = state -> count ;
 state -> error_sum += FFABS ( v ) ;
 drift += v ;
 if ( count == 128 ) {
 count >>= 1 ;
 drift >>= 1 ;
 state -> error_sum >>= 1 ;
 }
 count ++ ;
 if ( drift <= - count ) {
 if ( state -> bias > - 128 ) state -> bias -- ;
 drift += count ;
 if ( drift <= - count ) drift = - count + 1 ;
 }
 else if ( drift > 0 ) {
 if ( state -> bias < 127 ) state -> bias ++ ;
 drift -= count ;
 if ( drift > 0 ) drift = 0 ;
 }
 state -> drift = drift ;
 state -> count = count ;
 }


MP4::Properties::Properties(File *file, MP4::Atoms *atoms, ReadStyle style)
  : AudioProperties(style)
{
  d = new PropertiesPrivate;

  MP4::Atom *moov = atoms->find("moov");
  if(!moov) {
    debug("MP4: Atom 'moov' not found");
    return;
  }

  MP4::Atom *trak = 0;
  ByteVector data;

  MP4::AtomList trakList = moov->findall("trak");
  for (unsigned int i = 0; i < trakList.size(); i++) {
    trak = trakList[i];
    MP4::Atom *hdlr = trak->find("mdia", "hdlr");
    if(!hdlr) {
      debug("MP4: Atom 'trak.mdia.hdlr' not found");
      return;
    }
    file->seek(hdlr->offset);
    data = file->readBlock(hdlr->length);
    if(data.mid(16, 4) == "soun") {
      break;
    }
    trak = 0;
  }
  if (!trak) {
    debug("MP4: No audio tracks");
    return;
  }

  MP4::Atom *mdhd = trak->find("mdia", "mdhd");
  if(!mdhd) {
    debug("MP4: Atom 'trak.mdia.mdhd' not found");
    return;
  }

  file->seek(mdhd->offset);
  data = file->readBlock(mdhd->length);
  if(data[8] == 0) {
    unsigned int unit = data.mid(20, 4).toUInt();
    unsigned int length = data.mid(24, 4).toUInt();
    d->length = length / unit;
  }
  else {
    long long unit = data.mid(28, 8).toLongLong();
    long long length = data.mid(36, 8).toLongLong();
    d->length = int(length / unit);
  }

  MP4::Atom *atom = trak->find("mdia", "minf", "stbl", "stsd");
  if(!atom) {
    return;
  }

  file->seek(atom->offset);
  data = file->readBlock(atom->length);
  if(data.mid(20, 4) == "mp4a") {
    d->channels = data.mid(40, 2).toShort();
    d->bitsPerSample = data.mid(42, 2).toShort();
    d->sampleRate = data.mid(46, 4).toUInt();
    if(data.mid(56, 4) == "esds" && data[64] == 0x03) {
      long pos = 65;
      if(data.mid(pos, 3) == "\x80\x80\x80") {
        pos += 3;
      }
      pos += 4;
      if(data[pos] == 0x04) {
        pos += 1;
        if(data.mid(pos, 3) == "\x80\x80\x80") {
          pos += 3;
        }
        pos += 10;
        d->bitrate = (data.mid(pos, 4).toUInt() + 500) / 1000;
      }
    }
  }
}


void ff_h264_direct_ref_list_init(H264Context * const h){ MpegEncContext * const s = &h->s; Picture * const ref1 = &h->ref_list[1][0]; Picture * const cur = s->current_picture_ptr; int list, j, field; int sidx= (s->picture_structure&1)^1; int ref1sidx = (ref1->f.reference&1)^1; for(list=0; list<2; list++){ cur->ref_count[sidx][list] = h->ref_count[list]; for(j=0; j<h->ref_count[list]; j++) cur->ref_poc[sidx][list][j] = 4 * h->ref_list[list][j].frame_num + (h->ref_list[list][j].f.reference & 3); } if(s->picture_structure == PICT_FRAME){ memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0])); memcpy(cur->ref_poc [1], cur->ref_poc [0], sizeof(cur->ref_poc [0])); } cur->mbaff= FRAME_MBAFF; h->col_fieldoff= 0; if(s->picture_structure == PICT_FRAME){ int cur_poc = s->current_picture_ptr->poc; int *col_poc = h->ref_list[1]->field_poc; h->col_parity= (FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc)); ref1sidx=sidx= h->col_parity; } else if (!(s->picture_structure & h->ref_list[1][0].f.reference) && !h->ref_list[1][0].mbaff) { // FL -> FL & differ parity h->col_fieldoff = 2 * h->ref_list[1][0].f.reference - 3; } if (cur->f.pict_type != AV_PICTURE_TYPE_B || h->direct_spatial_mv_pred) return; for(list=0; list<2; list++){ fill_colmap(h, h->map_col_to_list0, list, sidx, ref1sidx, 0); if(FRAME_MBAFF) for(field=0; field<2; field++) fill_colmap(h, h->map_col_to_list0_field[field], list, field, field, 1); } }


static int qemuMonitorTextParseBlockJob ( const char * text , const char * device , virDomainBlockJobInfoPtr info ) {
 const char * next = NULL ;
 int ret = 0 ;
 if ( strstr ( text , "Device '" ) && strstr ( text , "' not found" ) ) {
 qemuReportError ( VIR_ERR_OPERATION_INVALID , "%s" , _ ( "Device not found" ) ) ;
 return - 1 ;
 }
 if ( strstr ( text , "Device '" ) && strstr ( text , "' is in use" ) ) {
 qemuReportError ( VIR_ERR_OPERATION_FAILED , _ ( "Device %s in use" ) , device ) ;
 return - 1 ;
 }
 if ( strstr ( text , "has not been activated" ) ) {
 qemuReportError ( VIR_ERR_OPERATION_INVALID , \ _ ( "No active operation on device: %s" ) , device ) ;
 return - 1 ;
 }
 if ( strstr ( text , "No active jobs" ) ) {
 return 0 ;
 }
 if ( strstr ( text , "Operation is not supported" ) ) {
 qemuReportError ( VIR_ERR_OPERATION_INVALID , _ ( "Operation is not supported for device: %s" ) , device ) ;
 return - 1 ;
 }
 if ( STREQ ( text , "" ) ) return 0 ;
 do {
 ret = qemuMonitorTextParseBlockJobOne ( text , device , info , & next ) ;
 text = next ;
 }
 while ( text && ret == - EAGAIN ) ;
 if ( ret < 0 ) return - 1 ;
 return ret ;
 }


static int rcancelrequested ( void ) {
 return InterruptPending && ( QueryCancelPending || ProcDiePending ) ;
 }


int Dispatcher::getparam( size_t N, int defaultval )
{
  int ret = defaultval;
  if ( !parsed ) {
    parse_params();
  }

  if ( parsed_params.size() > N ) {
    ret = parsed_params[ N ];
  }
  if ( ret < 1 ) ret = defaultval;

  return ret;
}


static inline int find_pte (CPUState *env, mmu_ctx_t *ctx, int h, int rw) { #if defined(TARGET_PPC64) if (env->mmu_model == POWERPC_MMU_64B || env->mmu_model == POWERPC_MMU_64BRIDGE) return find_pte64(ctx, h, rw); #endif return find_pte32(ctx, h, rw); }