示例#1
0
bool SkPDFImage::populate(SkPDFCatalog* catalog) {
    if (getState() == kUnused_State) {
        // Initializing image data for the first time.
        SkDynamicMemoryWStream dctCompressedWStream;
        if (!skip_compression(catalog) && fEncoder &&
                get_uncompressed_size(fBitmap, fSrcRect) > 1) {
            SkBitmap subset;
            // Extract subset
            if (!fBitmap.extractSubset(&subset, fSrcRect)) {
                return false;
            }
            size_t pixelRefOffset = 0;
            SkAutoTUnref<SkData> data(fEncoder(&pixelRefOffset, subset));
            if (data.get() && data->size() < get_uncompressed_size(fBitmap,
                                                                   fSrcRect)) {
                this->setData(data.get());

                insertName("Filter", "DCTDecode");
                insertInt("ColorTransform", kNoColorTransform);
                insertInt("Length", this->dataSize());
                setState(kCompressed_State);
                return true;
            }
        }
        // Fallback method
        if (!fStreamValid) {
            SkAutoTUnref<SkStream> stream(
                    extract_image_data(fBitmap, fSrcRect, fIsAlpha, NULL));
            this->setData(stream);
            fStreamValid = true;
        }
        return INHERITED::populate(catalog);
    } else if (getState() == kNoCompression_State &&
            !skip_compression(catalog) &&
            (SkFlate::HaveFlate() || fEncoder)) {
        // Compression has not been requested when the stream was first created,
        // but the new catalog wants it compressed.
        if (!getSubstitute()) {
            SkPDFStream* substitute = SkNEW_ARGS(SkPDFImage, (*this));
            setSubstitute(substitute);
            catalog->setSubstitute(this, substitute);
        }
        return false;
    }
    return true;
}
示例#2
0
static void compress_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
        grpc_call_element *elem,
        grpc_transport_stream_op *op) {
    call_data *calld = elem->call_data;

    GPR_TIMER_BEGIN("compress_start_transport_stream_op", 0);

    if (op->send_initial_metadata) {
        process_send_initial_metadata(elem, op->send_initial_metadata);
    }
    if (op->send_message != NULL && !skip_compression(elem) &&
            0 == (op->send_message->flags & GRPC_WRITE_NO_COMPRESS)) {
        calld->send_op = *op;
        calld->send_length = op->send_message->length;
        calld->send_flags = op->send_message->flags;
        continue_send_message(exec_ctx, elem);
    } else {
        /* pass control down the stack */
        grpc_call_next_op(exec_ctx, elem, op);
    }

    GPR_TIMER_END("compress_start_transport_stream_op", 0);
}
示例#3
0
/** Filter's "main" function, called for any incoming grpc_transport_stream_op
 * instance that holds a non-zero number of send operations, accesible to this
 * function in \a send_ops.  */
static void process_send_ops(grpc_call_element *elem,
                             grpc_stream_op_buffer *send_ops) {
  call_data *calld = elem->call_data;
  channel_data *channeld = elem->channel_data;
  size_t i;
  int did_compress = 0;

  /* In streaming calls, we need to reset the previously accumulated slices */
  gpr_slice_buffer_reset_and_unref(&calld->slices);
  for (i = 0; i < send_ops->nops; ++i) {
    grpc_stream_op *sop = &send_ops->ops[i];
    switch (sop->type) {
      case GRPC_OP_BEGIN_MESSAGE:
        /* buffer up slices until we've processed all the expected ones (as
         * given by GRPC_OP_BEGIN_MESSAGE) */
        calld->remaining_slice_bytes = sop->data.begin_message.length;
        if (sop->data.begin_message.flags & GRPC_WRITE_NO_COMPRESS) {
          calld->has_compression_algorithm = 1; /* GPR_TRUE */
          calld->compression_algorithm = GRPC_COMPRESS_NONE;
        }
        break;
      case GRPC_OP_METADATA:
        if (!calld->written_initial_metadata) {
          /* Parse incoming request for compression. If any, it'll be available
           * at calld->compression_algorithm */
          grpc_metadata_batch_filter(&(sop->data.metadata),
                                     compression_md_filter, elem);
          if (!calld->has_compression_algorithm) {
            /* If no algorithm was found in the metadata and we aren't
             * exceptionally skipping compression, fall back to the channel
             * default */
            calld->compression_algorithm =
                channeld->default_compression_algorithm;
            calld->has_compression_algorithm = 1; /* GPR_TRUE */
          }
          /* hint compression algorithm */
          grpc_metadata_batch_add_tail(
              &(sop->data.metadata), &calld->compression_algorithm_storage,
              GRPC_MDELEM_REF(channeld->mdelem_compression_algorithms
                                  [calld->compression_algorithm]));

          /* convey supported compression algorithms */
          grpc_metadata_batch_add_tail(
              &(sop->data.metadata), &calld->accept_encoding_storage,
              GRPC_MDELEM_REF(channeld->mdelem_accept_encoding));

          calld->written_initial_metadata = 1; /* GPR_TRUE */
        }
        break;
      case GRPC_OP_SLICE:
        if (skip_compression(channeld, calld)) continue;
        GPR_ASSERT(calld->remaining_slice_bytes > 0);
        /* Increase input ref count, gpr_slice_buffer_add takes ownership.  */
        gpr_slice_buffer_add(&calld->slices, gpr_slice_ref(sop->data.slice));
        GPR_ASSERT(GPR_SLICE_LENGTH(sop->data.slice) >=
                   calld->remaining_slice_bytes);
        calld->remaining_slice_bytes -=
            (gpr_uint32)GPR_SLICE_LENGTH(sop->data.slice);
        if (calld->remaining_slice_bytes == 0) {
          did_compress =
              compress_send_sb(calld->compression_algorithm, &calld->slices);
        }
        break;
      case GRPC_NO_OP:
        break;
    }
  }

  /* Modify the send_ops stream_op_buffer depending on whether compression was
   * carried out */
  if (did_compress) {
    finish_compressed_sopb(send_ops, elem);
  }
}
示例#4
0
static void compress_start_transport_stream_op_batch(
    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
    grpc_transport_stream_op_batch *op) {
  call_data *calld = elem->call_data;

  GPR_TIMER_BEGIN("compress_start_transport_stream_op_batch", 0);

  if (op->cancel_stream) {
    GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error);
    gpr_atm cur = gpr_atm_full_xchg(
        &calld->send_initial_metadata_state,
        CANCELLED_BIT | (gpr_atm)op->payload->cancel_stream.cancel_error);
    switch (cur) {
      case HAS_COMPRESSION_ALGORITHM:
      case NO_COMPRESSION_ALGORITHM:
      case INITIAL_METADATA_UNSEEN:
        break;
      default:
        if ((cur & CANCELLED_BIT) == 0) {
          grpc_transport_stream_op_batch_finish_with_failure(
              exec_ctx, (grpc_transport_stream_op_batch *)cur,
              GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error));
        } else {
          GRPC_ERROR_UNREF((grpc_error *)(cur & ~CANCELLED_BIT));
        }
        break;
    }
  }

  if (op->send_initial_metadata) {
    bool has_compression_algorithm;
    grpc_error *error = process_send_initial_metadata(
        exec_ctx, elem,
        op->payload->send_initial_metadata.send_initial_metadata,
        &has_compression_algorithm);
    if (error != GRPC_ERROR_NONE) {
      grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, op, error);
      return;
    }
    gpr_atm cur;
  retry_send_im:
    cur = gpr_atm_acq_load(&calld->send_initial_metadata_state);
    GPR_ASSERT(cur != HAS_COMPRESSION_ALGORITHM &&
               cur != NO_COMPRESSION_ALGORITHM);
    if ((cur & CANCELLED_BIT) == 0) {
      if (!gpr_atm_rel_cas(&calld->send_initial_metadata_state, cur,
                           has_compression_algorithm
                               ? HAS_COMPRESSION_ALGORITHM
                               : NO_COMPRESSION_ALGORITHM)) {
        goto retry_send_im;
      }
      if (cur != INITIAL_METADATA_UNSEEN) {
        grpc_call_next_op(exec_ctx, elem,
                          (grpc_transport_stream_op_batch *)cur);
      }
    }
  }
  if (op->send_message) {
    gpr_atm cur;
  retry_send:
    cur = gpr_atm_acq_load(&calld->send_initial_metadata_state);
    switch (cur) {
      case INITIAL_METADATA_UNSEEN:
        if (!gpr_atm_rel_cas(&calld->send_initial_metadata_state, cur,
                             (gpr_atm)op)) {
          goto retry_send;
        }
        break;
      case HAS_COMPRESSION_ALGORITHM:
      case NO_COMPRESSION_ALGORITHM:
        if (!skip_compression(elem,
                              op->payload->send_message.send_message->flags,
                              cur == HAS_COMPRESSION_ALGORITHM)) {
          calld->send_op = op;
          calld->send_length = op->payload->send_message.send_message->length;
          calld->send_flags = op->payload->send_message.send_message->flags;
          continue_send_message(exec_ctx, elem);
        } else {
          /* pass control down the stack */
          grpc_call_next_op(exec_ctx, elem, op);
        }
        break;
      default:
        if (cur & CANCELLED_BIT) {
          grpc_transport_stream_op_batch_finish_with_failure(
              exec_ctx, op,
              GRPC_ERROR_REF((grpc_error *)(cur & ~CANCELLED_BIT)));
        } else {
          /* >1 send_message concurrently */
          GPR_UNREACHABLE_CODE(break);
        }
    }
  } else {