Skip to content

Commit

Permalink
Move CommandString nodes to their own file
Browse files Browse the repository at this point in the history
  • Loading branch information
lilith committed Dec 10, 2020
1 parent b88bb14 commit 9a12f7f
Show file tree
Hide file tree
Showing 3 changed files with 245 additions and 240 deletions.
243 changes: 243 additions & 0 deletions imageflow_core/src/flow/nodes/command_string.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
use super::internal_prelude::*;
use imageflow_riapi::sizing::{Layout, AspectRatio, LayoutError};
use imageflow_types::{ConstraintMode, ImageInfo};
use itertools::Itertools;

pub static COMMAND_STRING: CommandStringDef = CommandStringDef{};
pub static COMMAND_STRING_POST_TRANSLATE: CommandStringPostTranslateDef = CommandStringPostTranslateDef {};
pub static COMMAND_STRING_POST_DECODE: CommandStringPostDecodeDef = CommandStringPostDecodeDef {};



fn get_decoder_mime(ctx: &mut OpCtxMut, ix: NodeIndex) -> Result<Option<String>>{
let decoders = ctx.get_decoder_io_ids_and_indexes(ix);
if let Some((io_id, _)) = decoders.first(){
Ok(Some(ctx.c.get_unscaled_rotated_image_info(*io_id)?.preferred_mime_type))
}
else{
Ok(None)
}

}

fn get_expand(ctx: &mut OpCtxMut, ix: NodeIndex) -> Result<::imageflow_riapi::ir4::Ir4Expand>{
let input = ctx.first_parent_frame_info_some(ix).ok_or_else(|| nerror!(crate::ErrorKind::InvalidNodeConnections, "CommandString node requires that its parent nodes be perfectly estimable"))?;

let mut image_info: Option<ImageInfo> = None;
if let Some((io_id, decoder_ix)) = ctx.get_decoder_io_ids_and_indexes(ix).first(){
image_info = Some(ctx.c.get_unscaled_rotated_image_info(*io_id).map_err(|e| e.at(here!()))?);

}

let params = &ctx.weight(ix).params;
if let NodeParams::Json(s::Node::CommandString{ref kind, ref value, ref decode, ref encode, ref watermarks}) =
*params {
match *kind {
s::CommandStringKind::ImageResizer4 => {
Ok(::imageflow_riapi::ir4::Ir4Expand {
i: ::imageflow_riapi::ir4::Ir4Command::QueryString(value.to_owned()),
encode_id: *encode,
watermarks: watermarks.clone(),
source: ::imageflow_riapi::ir4::Ir4SourceFrameInfo {
w: input.w,
h: input.h,
fmt: input.fmt,
original_mime: get_decoder_mime(ctx,ix)?
},
reference_width: image_info.as_ref().map(|i| i.image_width).unwrap_or(input.w),
reference_height: image_info.as_ref().map(|i| i.image_height).unwrap_or(input.h),

})
}
}
}else{
Err(nerror!(crate::ErrorKind::NodeParamsMismatch, "Need CommandString, got {:?}", params))
}
}



#[derive(Debug,Clone)]
pub struct CommandStringPostDecodeDef;



impl NodeDef for CommandStringPostDecodeDef {
fn fqn(&self) -> &'static str{
"imazen.command_string_post_decode"
}
fn edges_required(&self, p: &NodeParams) -> Result<(EdgesIn, EdgesOut)>{
Ok((EdgesIn::OneInput, EdgesOut::Any))
}
fn validate_params(&self, p: &NodeParams) -> Result<()>{
Ok(()) //TODO: need way to provide warnings
}
fn estimate(&self, ctx: &mut OpCtxMut, ix: NodeIndex) -> Result<FrameEstimate>{
let old_estimate = ctx.weight(ix).frame_est;

if old_estimate == FrameEstimate::InvalidateGraph{
Ok(FrameEstimate::Impossible)
} else {
let e = get_expand(ctx, ix).map_err(|e| e.at(here!()))?;

let decode_commands_result = e.get_decode_commands();

match decode_commands_result{
Err(LayoutError::ContentDependent) | Ok(None) => {},
Ok(Some(commands)) => {
for command in commands {
//Send command to codec
for (io_id, decoder_ix) in ctx.get_decoder_io_ids_and_indexes(ix) {
ctx.c.tell_decoder(io_id, command.clone()).map_err(|e| e.at(here!()))?;
}
}
}
Err(e) => {
return Err(FlowError::from_layout(e).at(here!()));
}
}


Ok(FrameEstimate::InvalidateGraph)
}
}
fn can_expand(&self) -> bool{
true
}

fn expand(&self, ctx: &mut OpCtxMut, ix: NodeIndex) -> Result<()> {

let e = get_expand(ctx, ix).map_err(|e| e.at(here!()))?;


match e.expand_steps().map_err(|e| FlowError::from_layout(e).at(here!())) {
Ok(r) => {
//TODO: Find a way to expose warnings
ctx.replace_node(ix, r.steps.unwrap().into_iter().map( Node::from).collect::<>());
Ok(())
}
Err(e) => {
//TODO: reparse to get warnings
Err(e)
}
}
}
}





#[derive(Debug,Clone)]
pub struct CommandStringPostTranslateDef;
impl NodeDef for CommandStringPostTranslateDef{

fn fqn(&self) -> &'static str{
"imazen.command_string_post_translate"
}
fn estimate(&self, ctx: &mut OpCtxMut, ix: NodeIndex) -> Result<FrameEstimate>{
Ok(FrameEstimate::Impossible)
}
fn edges_required(&self, p: &NodeParams) -> Result<(EdgesIn, EdgesOut)> {
Ok((EdgesIn::OneInput, EdgesOut::Any))
}
fn validate_params(&self, p: &NodeParams) -> Result<()>{
Ok(())
}
fn can_expand(&self) -> bool{
true
}
fn expand(&self, ctx: &mut OpCtxMut, ix: NodeIndex) -> Result<()> {
let has_parent = ctx.first_parent_of_kind(ix, EdgeKind::Input).is_some();
let params = ctx.weight(ix).params.clone();
let params_copy = ctx.weight(ix).params.clone();

if let NodeParams::Json(s::Node::CommandString { kind, value, decode, encode, watermarks }) = params_copy {
if let Some(d_id) = decode {
if has_parent {
return Err(nerror!(crate::ErrorKind::InvalidNodeParams, "CommandString must either have decode: null or have no parent nodes. Specifying a value for decode creates a new decoder node."));
}
let decode_node = ::imageflow_riapi::ir4::Ir4Translate {
i: ::imageflow_riapi::ir4::Ir4Command::QueryString(value.to_owned()),
decode_id: Some(d_id),
encode_id: None,
watermarks,
}.get_decode_node_without_commands().unwrap();
ctx.replace_node(ix, vec![
Node::from(decode_node),
Node::n(&COMMAND_STRING_POST_DECODE, params)
]);
} else {
if !has_parent {
return Err(nerror!(crate::ErrorKind::InvalidNodeParams,"CommandString must have a parent node unless 'decode' has a numeric value. Otherwise it has no image source. "));
}
ctx.replace_node(ix, vec![
Node::n(&COMMAND_STRING_POST_DECODE, params)
]);
}
Ok(())
} else {
Err(nerror!(crate::ErrorKind::NodeParamsMismatch, "Need CommandString, got {:?}", params))
}
}
}



#[derive(Debug,Clone)]
pub struct CommandStringDef;
impl NodeDef for CommandStringDef{

fn fqn(&self) -> &'static str{
"imazen.command_string"
}
fn estimate(&self, ctx: &mut OpCtxMut, ix: NodeIndex) -> Result<FrameEstimate>{
Ok(FrameEstimate::Impossible)
}
fn edges_required(&self, p: &NodeParams) -> Result<(EdgesIn, EdgesOut)> {
Ok((EdgesIn::OneInput, EdgesOut::Any))
}
fn validate_params(&self, p: &NodeParams) -> Result<()>{
Ok(())
}
fn can_expand(&self) -> bool{
true
}
fn expand(&self, ctx: &mut OpCtxMut, ix: NodeIndex) -> Result<()> {
let has_parent = ctx.first_parent_of_kind(ix, EdgeKind::Input).is_some();
let params = ctx.weight(ix).params.clone();
let params_copy = ctx.weight(ix).params.clone();

if let NodeParams::Json(s::Node::CommandString { kind, value, decode, encode, watermarks }) = params_copy {
if let Some(d_id) = decode {
if has_parent {
return Err(nerror!(crate::ErrorKind::InvalidNodeParams, "CommandString must either have decode: null or have no parent nodes. Specifying a value for decode creates a new decoder node."));
}
} else {
if !has_parent {
return Err(nerror!(crate::ErrorKind::InvalidNodeParams,"CommandString must have a parent node unless 'decode' has a numeric value. Otherwise it has no image source. "));
}
}
let translation_result = ::imageflow_riapi::ir4::Ir4Translate {
i: ::imageflow_riapi::ir4::Ir4Command::QueryString(value.to_owned()),
decode_id: decode,
encode_id: encode,
watermarks,
}.translate().map_err(|e| FlowError::from_layout(e).at(here!()))?;

let translation_nodes = translation_result.steps.unwrap()
.into_iter().map(|n| {
match n{
imageflow_types::Node::CommandString {..} => Node::n(&COMMAND_STRING_POST_TRANSLATE, NodeParams::Json(n)),
other => Node::from(other)
}
}).collect_vec();

ctx.replace_node(ix, translation_nodes);

Ok(())
} else {
Err(nerror!(crate::ErrorKind::NodeParamsMismatch, "Need CommandString, got {:?}", params))
}
}
}
Loading

2 comments on commit 9a12f7f

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New misspellings found, please review:

  • noinspection
To accept these changes, run the following commands
perl -e '
my @expect_files=qw('".github/actions/spell-check/whitelist/0859c3bf2abc4d7651115c782f331a3c80710361.txt
.github/actions/spell-check/whitelist/1e65a9a670e8cc12661ef255598f4f50bcfec736.txt
.github/actions/spell-check/whitelist/45800a4d7eb5794e95f0c7e33318173eca9399ae.txt
.github/actions/spell-check/whitelist/54b3b066a6b4654f7e7a02e49e56a1b3c1c76c25.txt
.github/actions/spell-check/whitelist/5ae660e58f0dca219d9dd5801aeffa0e4ad6e8fa.txt
.github/actions/spell-check/whitelist/618f622b0f99f2500bd3dc383f7a2cef48b72e76.txt
.github/actions/spell-check/whitelist/6a296fb5e9634a56210e3203f82a4aa8d5687b4b.txt
.github/actions/spell-check/whitelist/b6bfaacf90bc278201634e4a1408d65de5a94c06.txt
.github/actions/spell-check/whitelist/c5b95641888e2ab165141518065246c44002e236.txt
.github/actions/spell-check/whitelist/dfa55b76a78f73416aad6f69a30deec1e54d3857.txt
.github/actions/spell-check/whitelist/e4840f3eb751a28d6a885096045c6f437a5e7000.txt
.github/actions/spell-check/whitelist/f27d11d29d5514de97a874a0323133887bb7caba.txt
.github/actions/spell-check/whitelist/whitelist.txt"');
@ARGV=@expect_files;
my @stale=qw('"aca
 ansii
 au
 benchmarkee
 binwrite
 bytepp
 bytesize
 castps
 cleanpath
 cmarker
 coderay
 colormap
 coord
 coverity
 cpath
 decompressor
 DGif
 dirs
 divisorx
 downcase
 DRB
 drmike
 dtv
 elsif
 EOI
 eprofile
 ERKNS
 eventmachine
 executables
 extname
 falsey
 federico
 ferror
 fileptr
 flowhq
 fsevent
 gdk
 gemspec
 GETJOCTET
 gmail
 gtk
 GUINT
 hexdigest
 HPROFILE
 ifp
 Ilib
 inotify
 insertf
 interposharpen
 iprofile
 JOCTET
 JPOOL
 jruby
 JWRN
 keepalive
 lcs
 leth
 LGPL
 Meh
 Memcheck
 MESSAGEBOX
 Minitest
 mmc
 mtime
 Nailgun
 nathanael
 nathanaeljones
 ncpu
 nokogiri
 objtracker
 obuf
 optparse
 outpng
 outputsize
 pngtopng
 portile
 PRId
 PRIu
 ramdisk
 rcov
 redhat
 REGEXPS
 rspec
 RTEST
 Rubocop
 rubyforge
 Rustdoc
 rvm
 SDK
 shortname
 Shoulda
 simd
 Sqr
 Terminfo
 TESTUNIT
 tmpfs
 toolkits
 uninit
 voidp
 WIDTHx
 winmgmts
 zedzone
 zlibsettings
 ZNK
 zucchi
 "');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
  if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
  next if /^($re)(?:$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spell-check/whitelist/9a12f7f7dfa5cff8dac8994f8638cafb2de09b28.txt";
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"CPATH noinspection "');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a) cmp lc($b)} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;'
git add .github/actions/spell-check/whitelist || echo '... you want to ensure .github/actions/spell-check/whitelist/9a12f7f7dfa5cff8dac8994f8638cafb2de09b28.txt is added to your repository...'
✏️ Contributor please read this
  • You can probably just add items into .github/actions/spell-check/whitelist/whitelist.txt.
  • If you need to use a specific token in one place and it shouldn't generally be used, you can
    add an item in .github/actions/spell-check/patterns.txt.

⚠️ Reviewers

At present, the action that triggered this message will not show its ❌ in this PR unless the branch is within this repository.
Thus, you should make sure that this comment has been addressed before merging this PR.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New misspellings found, please review:

  • noinspection
To accept these changes, run the following commands
perl -e '
my @expect_files=qw('".github/actions/spell-check/whitelist/0859c3bf2abc4d7651115c782f331a3c80710361.txt
.github/actions/spell-check/whitelist/1e65a9a670e8cc12661ef255598f4f50bcfec736.txt
.github/actions/spell-check/whitelist/45800a4d7eb5794e95f0c7e33318173eca9399ae.txt
.github/actions/spell-check/whitelist/54b3b066a6b4654f7e7a02e49e56a1b3c1c76c25.txt
.github/actions/spell-check/whitelist/5ae660e58f0dca219d9dd5801aeffa0e4ad6e8fa.txt
.github/actions/spell-check/whitelist/618f622b0f99f2500bd3dc383f7a2cef48b72e76.txt
.github/actions/spell-check/whitelist/6a296fb5e9634a56210e3203f82a4aa8d5687b4b.txt
.github/actions/spell-check/whitelist/b6bfaacf90bc278201634e4a1408d65de5a94c06.txt
.github/actions/spell-check/whitelist/c5b95641888e2ab165141518065246c44002e236.txt
.github/actions/spell-check/whitelist/dfa55b76a78f73416aad6f69a30deec1e54d3857.txt
.github/actions/spell-check/whitelist/e4840f3eb751a28d6a885096045c6f437a5e7000.txt
.github/actions/spell-check/whitelist/f27d11d29d5514de97a874a0323133887bb7caba.txt
.github/actions/spell-check/whitelist/whitelist.txt"');
@ARGV=@expect_files;
my @stale=qw('"aca
 ansii
 au
 benchmarkee
 binwrite
 bytepp
 bytesize
 castps
 cleanpath
 cmarker
 coderay
 colormap
 coord
 coverity
 cpath
 decompressor
 DGif
 dirs
 divisorx
 downcase
 DRB
 drmike
 dtv
 elsif
 EOI
 eprofile
 ERKNS
 eventmachine
 executables
 extname
 falsey
 federico
 ferror
 fileptr
 flowhq
 fsevent
 gdk
 gemspec
 GETJOCTET
 gmail
 gtk
 GUINT
 hexdigest
 HPROFILE
 ifp
 Ilib
 inotify
 insertf
 interposharpen
 iprofile
 JOCTET
 JPOOL
 jruby
 JWRN
 keepalive
 lcs
 leth
 LGPL
 Meh
 Memcheck
 MESSAGEBOX
 Minitest
 mmc
 mtime
 Nailgun
 nathanael
 nathanaeljones
 ncpu
 nokogiri
 objtracker
 obuf
 optparse
 outpng
 outputsize
 pngtopng
 portile
 PRId
 PRIu
 ramdisk
 rcov
 redhat
 REGEXPS
 rspec
 RTEST
 Rubocop
 rubyforge
 Rustdoc
 rvm
 SDK
 shortname
 Shoulda
 simd
 Sqr
 Terminfo
 TESTUNIT
 tmpfs
 toolkits
 uninit
 voidp
 WIDTHx
 winmgmts
 zedzone
 zlibsettings
 ZNK
 zucchi
 "');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
  if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
  next if /^($re)(?:$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spell-check/whitelist/9a12f7f7dfa5cff8dac8994f8638cafb2de09b28.txt";
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"CPATH noinspection "');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a) cmp lc($b)} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;'
git add .github/actions/spell-check/whitelist || echo '... you want to ensure .github/actions/spell-check/whitelist/9a12f7f7dfa5cff8dac8994f8638cafb2de09b28.txt is added to your repository...'
✏️ Contributor please read this
  • You can probably just add items into .github/actions/spell-check/whitelist/whitelist.txt.
  • If you need to use a specific token in one place and it shouldn't generally be used, you can
    add an item in .github/actions/spell-check/patterns.txt.

⚠️ Reviewers

At present, the action that triggered this message will not show its ❌ in this PR unless the branch is within this repository.
Thus, you should make sure that this comment has been addressed before merging this PR.

Please sign in to comment.